I am currently making a practise eCommerce website and I have encountered a problem with my styling, I can't figure out how to attach the button to the very bottom of the product container so that other items don't overstretch.
I would ideally like the containers to stretch and balance out the content to the length of the longest item.
Here is a picture of the issue
CSS:
.card-container {
max-width: 80%;
width: 80%;
margin: auto;
display: flex;
justify-content: center;
flex-wrap: wrap;
height: 500px;
}
.product-name {
font-size: 130%;
font-weight: bold;
color: black;
}
.image-container {
width: 80%;
height: 250px;
}
.description {
padding: 0 20px;
}
.link {
text-decoration: none;
}
.item-info {
line-height: 200%;
}
.card {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
max-width: 300px;
margin: 2em auto;
text-align: center;
font-family: arial;
width: 100%;
min-width: 300px;
}
.card img {
max-width: 250px;
max-height: 200px;
}
.price {
font-size: 22px;
}
.card button {
border: none;
outline: 0;
padding: 12px;
color: white;
background-color: #000;
text-align: center;
cursor: pointer;
width: 100%;
font-size: 18px;
}
.card button:hover {
opacity: 0.7;
}
JSX:
import './Home.css'
import { Link } from 'react-router-dom';
import { useState, useEffect } from 'react';
import fetchItems from '../../utils/fetchItems';
export const Home = () => {
const [ products, setProducts ]= useState([]);
useEffect(() => {
(async () => {
const response = await fetchItems('/products');
setProducts(response);
})()
}, []);
return(
<div>
<h1>Welcome to Sahara</h1>
<div className='card-container'>
{products.map(product => {
return(
<div className="card">
<img src={product.image} alt='product' />
<div className='item-info'>
<Link to={`/products/${product.id}`} className='link'><h4 className='product-name'>{product.name}</h4></Link>
<p className='seller'>{product.seller}</p>
<p className='price'>${product.price}</p>
<Link to='/cart'><button>Add to Cart</button></Link>
</div>
</div>
)
})}
</div>
</div>
)
}
Any help would be greatly appreciated.
Thank you.
An easy way to do this would be to have the the .card position: relative; and the .card button be set to position: absolute; Something similar to the below:
.card {
position: relative;
}
.card button {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
You could use position: absolute; to align the button to the bottom. Add these values to the stylesheet:
.card {
position: relative;
}
.card button {
position: absolute;
bottom: 0;
right: 0;
}
See this question for more information.
.card {
position: relative;
}
.card button {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
Related
I have a button that I want to be able to close if it's clicked outside the area of the popout. I tried adding a toggle class but I am not sure if I am doing it right. I used the example from geekforgeeks.
https://www.geeksforgeeks.org/how-to-toggle-an-element-class-in-javascript/
But I am getting the following error message:
Uncaught InvalidCharacterError: Failed to execute 'add' on 'DOMTokenList': The token provided ('function openPopOut() {popOut.classList.add("open");setTimeout(closePopOut, 8000);
}') contains HTML space characters, which are not valid in tokens.
Any pointers on how to proceed?
This is my code:
const activateBtn = document.querySelector(".activate-btn");
const html = document.querySelector("html");
const popOut = document.querySelector(".pop-out");
const popOutCloseBtn = popOut.querySelector(".pop-out__close-btn");
function openPopOut() {
popOut.classList.add("open");
setTimeout(closePopOut, 8000);
}
function closePopOut() {
popOut.classList.remove("open");
}
// activateBtn.addEventListener("click", openPopOut);
activateBtn.addEventListener("click", function (e){
activateBtn.classList.add(openPopOut);
});
popOutCloseBtn.addEventListener("click", closePopOut);
html.addEventListener("click", function (e) {
if (e.target !== popOut) popOut.classList.remove("pop-out");
});
body {
display: flex;
width: 100%;
height: 100%;
}
button {
cursor: pointer;
}
.activate-btn {
margin: auto;
}
.pop-out {
position: absolute;
bottom: 32px;
right: 32px;
display: flex;
width: 175px;
height: 100px;
background-color: cornflowerblue;
border: 1px solid;
border-radius: 4px;
transform: translateX(210px);
transition: transform 333ms ease-out;
}
.pop-out__close-btn {
position: absolute;
top: 8px;
right: 8px;
background-color: transparent;
font-weight: bold;
border: none;
}
.pop-out__msg {
margin: auto;
}
.pop-out.open {
transform: translateX(0);
}
<html>
<button class="activate-btn">Activate</button>
<div class="pop-out">
<button class="pop-out__close-btn">X</button>
<h3 class="pop-out__msg">Hello!</h3>
</div>
</html>
Fixed your code.
The popup shows when you click the button, when you click outside the popup, it disappears.
const activateBtn = document.querySelector(".activate-btn");
const html = document.querySelector("html");
const popOut = document.querySelector(".pop-out");
const popOutCloseBtn = popOut.querySelector(".pop-out__close-btn");
function openPopOut() {
popOut.classList.add("open");
setTimeout(closePopOut, 8000);
}
function closePopOut() {
popOut.classList.remove("open");
}
// activateBtn.addEventListener("click", openPopOut);
activateBtn.addEventListener("click", function (e){
openPopOut();
});
popOutCloseBtn.addEventListener("click", closePopOut);
document.addEventListener("click", function (e) {
if (e.target !== popOut && e.target !== activateBtn) closePopOut();
});
body {
display: flex;
width: 100%;
height: 100%;
overflow-x: hidden;
}
button {
cursor: pointer;
}
.activate-btn {
margin: auto;
}
.pop-out {
position: absolute;
bottom: 32px;
right: 32px;
display: flex;
width: 175px;
height: 100px;
background-color: cornflowerblue;
border: 1px solid;
border-radius: 4px;
transform: translateX(210px);
transition: transform 333ms ease-out;
}
.pop-out__close-btn {
position: absolute;
top: 8px;
right: 8px;
background-color: transparent;
font-weight: bold;
border: none;
}
.pop-out__msg {
margin: auto;
}
.pop-out.open {
transform: translateX(0);
display: flex;
}
<html>
<button class="activate-btn">Activate</button>
<div class="pop-out">
<button class="pop-out__close-btn">X</button>
<h3 class="pop-out__msg">Hello!</h3>
</div>
</html>
My sandbox on JSFIDDLE
When 'OPEN' is clicked, the content div should expand to full width, but it ended up expanding by 100px width like on the red box. I tried to set width: 100%, in the gray box div and it didn't work.
In the .content class, I had the width set to 100vw without margin: 0 auto and it expanded 100% width to the right side, not screen-fulled size.
[]
I'm testing this function before I deploy it on my website.
jQuery -
$(".openit").on("click", function() {
$(".expandBG").toggleClass("content");
$(".openit").hide();
$(".closeit").show();
$(".text").delay(500).fadeIn();
});
$(".closeit").on("click", function() {
$(".expandBG").toggleClass("content");
$(".openit").show();
$(".closeit").hide();
$(".text").hide();
});
HTML -
<div class="wrapper">
<div class="back">BG
<div class="expandBG">
<div class="openit">OPEN</div>
<div class="flex-col">
<div class="closeit">CLOSE</div>
<div class="content text" style="display: none;">
<div>(CONTENT HERE)</div>
</div>
</div>
</div>
</div>
</div>
CSS -
body {
background-color: #000;
}
.wrapper {
width: 100%;
margin: 0 auto;
text-align: center;
border: solid red 1px;
}
.back {
position: relative;
color: #fff;
width: 110px;
height: 110px;
background-color: red;
margin: 0 auto;
text-align: center;
display: block;
}
.expandBG {
display: block;
width: 100px;
height: 100px;
transition: ease 0.3s;
background-color: #192D38;
overflow: hidden;
margin: 0 auto;
bottom: 0;
text-align: center;
font-family: sans-serif;
color: #fff;
position: relative;
}
.flex-col {
flex-direction: column;
}
.openit {
display: block;
text-align: center;
height: 100%;
cursor: pointer;
margin: 0 auto;
}
.closeit {
display: block;
text-align: center;
cursor: pointer;
width: 100%;
margin: 0 auto;
z-index: 1;
position: relative;
}
.text {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: -25px;
}
.content {
width: 100%;
height: 50vw;
position: relative;
margin: 0 auto;
}
It's because of the div with a class name back. increase the width of that div to 100% when opneit is clicked and then back to its original size when closeit is clicked.
// add this to your CSS file
.w-full {
width: 100%
}
then include these two lines in your javaScript file
$(".openit").on("click", function() {
$(".back").addClass("w-full"); // This line has been added to your code.
$(".expandBG").toggleClass("content");
$(".openit").hide();
$(".closeit").show();
$(".text").delay(500).fadeIn();
});
$(".closeit").on("click", function() {
$(".back").removeClass("w-full"); // This line has been added to your code.
$(".expandBG").toggleClass("content");
$(".openit").show();
$(".closeit").hide();
$(".text").hide();
});
I'm writing a code for a UI for a certain group, and i have the following code:
App.js:
import React, { Component } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
import Helmet from 'react-helmet';
import TextField from "#mui/material/TextField";
import HRLOGO from './images/highradius-logo-3.png';
import ABCLOGO from './images/Group 20399.png';
export default class App extends Component
{
state = {};
render()
{
return (
<div className="Bod">
<div>
<img src={HRLOGO} alt="" className="container-div"/>
</div>
<div>
<img src={ABCLOGO} alt="" className="container-div2"/>
</div>
<Helmet>
<style>{'body { background-color: #2d4250; }'}</style>
</Helmet>
<div>
<h1 className="InvoiceStyle">Invoice List</h1>
</div>
<div className="Rectangle">
</div>
<div className="search">
<TextField
id="outlined-basic"
variant="outlined"
fullWidth
label="Search Customer ID"
/>
</div>
<footer className="Privacy">
<p>
Pivacy Policy
</p>
</footer >
</div>
);
}
}
App.css:
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
#media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.Rectangle {
width: 2000px;
height: 500px;
background: #293d48;
position: fixed;
top: 165px;
}
.container-div {
display: flex;
height: 8vh;
width: 20vw;
position: fixed;
top: 8px;
right: 600px;
text-align: center;
}
.InvoiceStyle {
display: flex;
color: #fff;
font-family: "Open Sans";
position: fixed;
top: 100px;
left: 25px;
}
.container-div2 {
display: flex;
height: 8vh;
width: 20vw;
position: fixed;
top: 7px;
left: 15px;
}
.Privacy {
display: flex;
position: fixed;
top: 700px;
left: 600px;
}
.search {
position: fixed;
top: 175px;
left: 600px;
width: 20%;
/* height: 40px; */
background-color: #fff;
border: none;
border-top-left-radius: 10px !important;
border-bottom-left-radius: 10px !important;
border-top-right-radius: 10px !important;
border-bottom-right-radius: 10px !important;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: rgb(11, 68, 253);
}
.App-link {
color: #ff0000;
}
#keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
How do i make it such that the images and text change according to the aspect area of the platform it is being viewed it? For example, normally on a 16:9 ratio it looks like this:
When browser size changes:
How do I prevent this? Any help would be useful. Thanks!
I am working on a personal portfolio page using ReactJS. I am currently trying to create a project page that has rows of flipping cards, however, whenever the cards reach their max-width and move to the next line the card always starts in the center of the page when it needs to start on left. I have tried creating a row wrapper to float: left which breaks the application and a multitude of other ways but I would like to see the best way to create dynamic rows and columns from a mapped array and start new rows from the left. added an image to highlight the issue
Projects.js
import React, { Fragment } from 'react';
import Card from '../common/Card/Card';
import { PROJECTS } from "../../shared/constants/projects";
import "./projects.scss";
const Projects = () => {
return (
<Fragment>
<div className="grid">
{
PROJECTS.map((project, i) => {
return (
<Card animatedCard={true} project={project} key={i} />
)
})
}
</div>
</Fragment>
)
}
export default Projects;
projects.scss
.grid {
width: 60%;
text-align: center;
margin: 0 20% 0 20%;
}
Card.js
import React, { Fragment } from 'react';
import CardFront from './CardFront';
import "./card.scss";
import CardBack from './CardBack';
const Card = props => {
return (
<Fragment>
{props.animatedCard ?
<div className="card-container">
<div className="card-body">
<CardBack project={props.project}/>
<CardFront project={props.project} />
</div>
</div> : null
}
</Fragment>
)
}
card.scss
.button-wrapper {
height: 200px;
bottom: 0;
}
.card-container {
display: inline-block;
position: relative;
z-index: 1;
margin: 50px 25px 0px 25px;
width: 300px;
height: 400px;
perspective: 1000px;
}
.card-body {
width: 100%;
height: 100%;
background-color: white;
transform-style: preserve-3d;
transition: all 0.5s linear;
}
.card-container:hover .card-body {
transform: rotateY(180deg);
}
.card-container:hover > .card-body > .side-front {
opacity: 0;
visibility: hidden;
transition: opacity 1s ease-in, visibility 0.75s linear;
}
.card-side {
position: absolute;
top: 0;
overflow: hidden;
width: 100%;
height: 100%;
color: #8e8d8a;
backface-visibility: hidden;
font-family: sans-serif;
text-align: center;
box-shadow: 0 10px 35px rgba(50, 50, 93, 0.1), 0 2px 15px rgba(0, 0, 0, 0.07);
}
.card-header-img {
max-width: 100%;
max-height: 123px;
margin: 0;
padding: 0;
}
.card-technologies {
list-style: none;
width: 70%;
}
.card-technologies-item {
border-bottom: 1px solid #eee;
margin-bottom: 15px;
padding: 0.75rem;
}
.description {
margin: 30px 20px 20px 20px;
font-size: 18px;
font-weight: 400;
height: 240px;
}
.side-front [class^="col-xs"]:first-of-type {
padding-left: 0;
}
.side-back {
z-index: 2;
text-align: center;
transform: rotateY(180deg);
}
This is happening since you are using text-align: center; in your .grid css.
If you remove it all the cards in the row should start at the left end of the row:
.grid {
width: 60%;
margin: 0 20% 0 20%;
}
Another alternative would be making your .grid a flexbox:
.grid {
width: 60%;
margin: 0 20% 0 20%;
display: flex;
flex-wrap: nowrap;
}
I'm working on my own to create a post css stype for a blogspot.com template that I purchased recently. With so many tutorials, I made exactly what I want, but the carousel have the issue that does not properly with the left control. Can you help me?
I was searching on YouTube. Most of the code is a modification from something of someone else (I'm a Graphic Designer who barely know the basics of HTML).
Thanks a lot!
const carousel2 = document.querySelector('.carousel2');
const slider2 = document.querySelector('.slider2');
const next = document.querySelector('.next');
const prev = document.querySelector('.prev');
let direction;
next.addEventListener('click', function() {
direction = -1;
carousel2.style.justifyContent = 'flex-start';
slider2.style.transform = 'translate(-20%)';
});
prev.addEventListener('click', function() {
if (direction === -1) {
direction = 1;
slider2.appendChild(slider2.firstElementChild);
}
carousel2.style.justifyContent = 'flex-end';
slider2.style.transform = 'translate(20%)';
});
slider2.addEventListener('transitionend', function() {
// get the last element and append it to the front
if (direction === 1) {
slider2.prepend(slider2.lastElementChild);
} else {
slider2.appendChild(slider2.firstElementChild);
}
slider2.style.transition = 'none';
slider2.style.transform = 'translate(0)';
setTimeout(() => {
slider2.style.transition = 'all 0.5s';
})
}, false);
/*----------POST CAROUSEL SLIDER------------
---------------------------------------------------*/
.carousel-general-container {
max-width: 780px;
height: auto;
width: 100%;
margin: 0px auto;
padding-bottom: 20px;
}
/*--POST CAROUSEL 2--*/
.slider-container2 {
max-width: 100%;
height: auto;
width: 100%;
margin: 10px auto;
}
.carousel2 {
background: #fff;
border: 2px solid transparent;
border-radius: 6px;
width: 100%;
display: flex;
justify-content: flex-start;
overflow: hidden;
position: relative;
}
.slider2 {
display: flex;
height: 100%;
width: 500%;
flex-shrink: 0;
transition: all 0.5s;
}
.slider2 div {
flex-basis: 20%;
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
}
.slider2 div img {
height: auto;
width: 100%;
}
.controls2 button.next {
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
cursor: pointer;
outline: none;
color: white;
}
.controls2 button.prev {
position: absolute;
left: 20px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
cursor: pointer;
outline: none;
color: white;
}
.controls2 button i {
font-size: 40px;
}
/*---------------------------------------------END--*/
<!--POST CAROUSEL CONTAINER-->
<div class="carousel-general-container">
<!--POST CAROUSEL SLIDER 2-->
<div class="slider-container2">
<div class="carousel2">
<div class="slider2">
<div>
<img src="https://1.bp.blogspot.com/-u0J4VE6mIeA/XyOZayGTTAI/AAAAAAAAHjc/UWqc7cn13CU4lsoQ6YXtJTu0FCmbGxuKACPcBGAYYCw/s1024/Templates-para-LIBROS.jpg">
</div>
<div>
<img src="https://1.bp.blogspot.com/-ujMXEoNvpA0/XyXhGwza0YI/AAAAAAAAHkM/NGONl1zblm0ufze1a0DLoCdKSCY_dbgxgCPcBGAYYCw/s1000/graffiti2.jpeg">
</div>
</div>
<div class="controls2">
<button class="next"><i class="material-icons">keyboard_arrow_right</i></button>
<button class="prev"><i class="material-icons">keyboard_arrow_left</i></button>
</div>
</div>
</div>
</div>
This is the codepen.
Thanks a lot!
why don't You use an already existing carousel prefab?
Doing a carousel yourself might teach You a lot of things but It will take a lot of your time!
I personally reccomend You Slick.js!
It is fully personalizable and It is compatible with both desktops and mobiles.
Here is a quick tutorial on how to set It up ;)