How to prevent absolute element from going off screen? - html

I'm setting up some conceptual functions (hence the probably botched way this is put together), but I'm running into an unforeseen issue with using position : absolute on the toast elements. On the right-hand products there's no issue besides the toast overlapping the products to its left (which is fine in this case), but when it triggers on the left column it extends outside the viewport.
That's why the class="diamond" is outside the toast itself, so that it can remain static regardless of the toast's position, since I assume position : absolute is not the ideal positioning for the toast.
So my question is, how can I achieve the intended effect of the toast triggering but remaining inside the viewport? My intention is for the diamond to be "anchored" to the button, with the toast itself dynamic on the horizontal axis.
Click the red square to open the toast, and the green one inside to close it.
function open(event) {
if (!event.target.closest(".product button")){
return false;
}
const parent = event.target.closest(".product");
const toast = parent.querySelector('.toast');
const diamond = parent.querySelector('.diamond');
toast.style.display = 'block';
diamond.style.display = 'block';
}
function close(event) {
if (!event.target.closest(".toast button")){
return false;
}
const product = event.target.closest(".product");
const toast = event.target.closest(".toast");
product.querySelector('.diamond').style.display = 'none';
toast.style.display = 'none';
}
addEventListener('click', open);
addEventListener('click', close);
.container {
display : flex;
flex-flow: row wrap;
justify-content : space-around;
height : 450px;
width : 300px;
background-color : grey;
}
.product {
position : relative;
height : 200px;
width : 130px;
background-color : blue;
}
.icon {
position : absolute;
top : 10px;
right : 10px;
height : 30px;
width : 30px;
background-color : red;
}
.diamond {
position : absolute;
display : none;
height : 10px;
width : 10px;
top : 50px;
right : 20px;
background-color : black;
transform : rotate(45deg);
}
.toast {
position : absolute;
display : none;
width : 160px;
height : 50px;
top : 55px;
right : 10px;
background-color : black;
border-style: solid;
border-width : thin;
border-color : red;
}
.close {
position : absolute;
display : block;
width : 20px;
height : 20px;
top : 15px;
right : 70px;
background-color : green;
}
<div class="container">
<div class="product">
<button class="icon"></button>
<div class="diamond"></div>
<div class="toast">
<button class="close"></button>
</div>
</div>
<div class="product">
<button class="icon"></button>
<div class="diamond"></div>
<div class="toast">
<button class="close"></button>
</div>
</div>
<div class="product">
<button class="icon"></button>
<div class="diamond"></div>
<div class="toast">
<button class="close"></button>
</div>
</div>
<div class="product">
<button class="icon"></button>
<div class="diamond"></div>
<div class="toast">
<button class="close"></button>
</div>
</div>
</div>

This can be the possible solution. Please replace toast css with the below css:
.toast {
position: absolute;
display: none;
width: 100%;
height: 50px;
top: 55px;
right: 0;
background-color: black;
border-style: solid;
border-width: thin;
border-color: red;
}
Hope this will help you!

Related

Why is the background color of my DIV element not visible? [duplicate]

This question already has answers here:
Bootstrap Rows and Columns - Do I need to use row?
(4 answers)
Closed 1 year ago.
/**This code doesnt change the color of the class row1**/
html, body {
font-family :'montserrat',sans-serif;
}
h1 {
border-left : 2px solid #00f28f;
font-size : 48px;
font-weight : 400;
padding-left : 20px;
}
.main {
margin-top : 80px;
}
form input {
background : #F0f0f0;
border : none;
font-size : 36px;
padding : 20px;
width : 100%;
transition : background 0s, border-left 0s;
}
form input:focus {
background : #fff;
border-left : 2pxsolid #000;
box-shadow : none;
outline : none;
}
button.button {
background : transparent;
border : none;
color : #00f2bf;
cursor : pointer;
font-size : 36px;
padding : 20px 24px;
transition : background 0s, border-left 0s;
}
button.button:hover {
background : #00f2bf;
color : #fff;
}
.row1 {
background : yellowgreen;
}
<link href="https://fonts.google.com/specimen/Poppins?preview.size=20" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="C:\Users\kalyanasundar.s\OneDrive - HCL Technologies Ltd\Desktop\proj\proj.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<header class="header">
<div class="container">
<div class="row">
<div class="col-xs-2 col-md-2">
<h1>Kalyan The Coder</h1>
</div>
</div>
</div>
</header>
<div class="main">
<div class="container2">
<div class="row1">
<form class="form">
<div class="col-xs-8 col-md-4">
<input type="text" id="TextBox1" placeholder="Enter your query">
</div>
<div class="col-xs-4 col-md-2">
<button type="submit" class="button">post</button>
</div>
This command works fine except that the row1 color doesn't change and not sure why.
If I change row1 to row on CSS, the color of header changes. I am not sure how to change the class in the CSS style sheet.
I am beginner and would like to explore more on this.
You need to give your element height.
It helps to simplify the problem. Currently, if you add height: 100px to your row1 class, the background becomes a visible yellowgreen as you desire:
.row1 {
background: yellowgreen;
height: 100px;
}
Let's show the difference with a simplified snippet:
.row-1 { background-color: yellowgreen; }
.row-2 {
height: 100px;
background-color: red;
}
<div class="row-1"></div>
<div class="row-2"></div>
Notice how you can't see row-1 here? Adding a height, padding, or anything else that expands the div's area will make it show:
.row-1 { background-color: yellowgreen; }
<div class="row-1">
<p>This should make the row visible.</p>
</div>

Changing the length of a shape based on a given value

I have designed a card-shaped rectangle, that has an inside integer value which is obtained from an angular module/class/type script.... I want to change the height of the shape based on the inside value: the larger the value, the longer the height of the rectangle.
so far, this is my code
<div class = "card">
<div class="content">
<p id = "name">
{{Card.lesson.Name}}
</p>
<p id = "time">
{{Card.duration.Hours}}
<span>
:
{{Card.duration.Minutes}}
</span>
</p>
</div>
<div class = "shape">
</div>
</div>
.card
{
width : 100px;
height : 150px;
background :#FFFFFF;
border: 1px solid #EEE2FA;
border-radius : 10px;
position: relative;
}
#name
{
position: relative;
text-align:center;
font-size:15px;
top:30px;
}
#time
{
position: relative;
text-align:center;
font-size:15px;
top:50px;
}
.shape
{
position: absolute;
display: block;
height:85%;
width: 3px;
background-color: blue;
padding-top: 0px;
top: 10px;
border-radius: 4px;
right: auto;
left: 8px;
padding-left: 8px;
}
The problem is, I have no Idea how to do so. how can I possibly relate Card.Duration.Hours to the height of the card?
You can use ngStyle to do so
You code will be like this:
<div class = "card" [ngStyle]="{'height': Card.duration.Hours + 'px'}">
<div class="content">
<p id = "name">
{{Card.lesson.Name}}
</p>
<p id = "time">
{{Card.duration.Hours}}
<span>
:
{{Card.duration.Minutes}}
</span>
</p>
</div>
<div class = "shape">
</div>
</div>
You can specify your own unit intead of px
Hope it helps.

ANGULAR 2: Floating button not floating CSS

Im very new to frontend development & angular 2. I was trying to program a floating button on the right bottom of the webapp that would allow users to open the shopping cart if needed (cart-button). The problem I have is that the button appears on the screen, put it does not readjust its position once scrolled down, its position is fixed to one spot and it wont move.
HTML:
<md-sidenav-container class="example-container">
<md-sidenav #sidenav class="example-sidenav">
<div class="scroll">
<md-card *ngFor="let ticket of shoppingCart">
<md-card-title>{{ticket.product.name}}</md-card-title>
<md-card-subtitle>$ {{ticket.product.price}}</md-card-subtitle>
<md-card-subtitle>Quantity: {{ticket.quantity}}</md-card-subtitle>
<button md-icon-button (click)="removeProduct(ticket.product)">
<md-icon>delete</md-icon>
</button>
</md-card>
<button md-button class="checkout" (click)="openDialog()">CHECKOUT</button>
</div>
</md-sidenav>
<div id="cart-button">
<button md-icon-button (click)="openNav(sidenav)" id = "cart-button2">
<md-icon>shopping_cart</md-icon>
</button>
</div>
<app-banner *ngIf="!featured"></app-banner>
<form *ngIf="!featured" class="cont">
<md-input-container class="search">
<input mdInput placeholder="Search" type="text" (keyup)="onKeyUp(search.value)" #search>
</md-input-container>
<md-select placeholder="Categories" class="category">
<md-option *ngFor="let category of categories" (click)="change(category)">
{{ category }}
</md-option>
</md-select>
</form>
<md-grid-list cols="5" rowHeight="1:1.4" class="size">
<md-grid-tile *ngFor="let product of products" class="separation">
<md-card class="example-card">
<md-card-header>
<div md-card-avatar class="example-header-image"></div>
<md-card-title>${{product.price}}</md-card-title>
<md-card-subtitle>{{product.name}}</md-card-subtitle>
</md-card-header>
<div class="image-container" [ngStyle]="{'background-image': 'url(' + product.imgUrl + ')'}" [routerLink]="['/product', product.id]">
</div>
<md-card-actions>
<button md-button (click)="addToCart(product.id, 1, sidenav)">ADD TO CART</button>
</md-card-actions>
</md-card>
</md-grid-tile>
</md-grid-list>
<div id="fidget-spinner-container" *ngIf="firstLoad">
<md-spinner id="fidget-spinner" *ngIf="!featured"></md-spinner>
</div>
</md-sidenav-container>
CSS:
.size {
width: 1400px;
margin:100px auto;
}
.example-card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,.3);
transition: 0.3s;
width: 400%;
border-radius: 5px;
}
.example-card:hover {
box-shadow: 0 10px 20px 0 rgba(0,0,0,0.5);
}
.example-header-image {
background-image: url('https://img2.hkrtcdn.com/1434/prd_143361_c_l.jpg');
background-size: cover;
}
.example-container {
position: relative;
width: 100%;
height: 100%;
border: 1px solid rgba(0, 0, 0, 0.5);
}
.example-sidenav-content {
display: flex;
height: 100%;
align-items: center;
justify-content: center;
}
.example-sidenav {
padding: 100px 50px 0 50px;
width: 250px;
}
.checkout {
bottom: 30px;
position: fixed;
}
.image-container {
width: 200px;
height: 200px;
background: white center no-repeat;
background-size: contain;
}
.mat-card-image:first-child {
margin-top: 0 !important;
}
.example-card {
margin:15px;
}
.scroll {
overflow-x: auto;
width:100%;
height:80%;
}
.cont {
width:70%;
padding-right:15%;
padding-left:15%;
padding-top: 330px;
display: inline-flex;
}
.search {
width:70%;
padding-left:10%;
/*margin-left: 30%;*/
/*margin-right: 30%;*/
}
#fidget-spinner {
margin:auto;
padding-bottom:50px;
}
.mat-option {
color: black;
}
#cart-button {
position:fixed;
width:60px;
height:60px;
bottom:40px;
right:40px;
background-color: #666666;
color:#FFF;
border-radius:50px;
text-align:center;
box-shadow: 2px 2px 3px #999;
}
.cart-button2 {
margin-top:22px;
}
.category {
padding-right:10%;
padding-top: 10.4px;
width:20%;
}
What I do typically is this in my main module component:
template: `
<div class="container-fluid" [ngStyle]="containerDivSize">
<router-outlet>
</router-outlet>
</div>
`,
So the template above for the container defines the div to be exactly the size of the screen, and by way of setting an Observer on window resize events below, containerDivSize adapts to changes in the window size and orientation, so if the user resizes the window we get the updates. This means we know the exact pixel dimensions of the screen, and we size our containing div to fill the window regardless of any changes.
containerDivSize: any;
constructor(){}
ngOnInit() {
Observable.fromEvent(window, 'resize')
.map(getWindowSize)
.subscribe(
windowSize$ => {
var windowHeight = windowSize$.height;
var windowWidth = windowSize$.width;
this.containerDivSize = {
'height': windowHeight + 'px'
'width': windowHeight + 'px'
}
});
}
You can use this same method to define a button position style that takes the window width and height, subtract the button size and apply it to your button, which will always stay fixed just inside the bottom right corner of the window no matter what the user does (scroll or resize the window).
Maybe something like this:
buttonPosition: any;
var buttonVerticalPosition = windowSize$.height-50;
var buttonHorizontalPosition = windowSize$.width-120;
this.buttonPosition = {
'position': 'absolute',
'top': buttonVerticalPosition + 'px',
'left': buttonHorizontalPosition + 'px'
}
Then add that class to your button.
<button class="btn btn-sm btn-default buttonPosition" >View Cart</button>
The problem is you are using Materal2 which is using transform3D in its style. Due to this relative postion is not working. You should place your button in this component. It takes whatever you put in it and places it in the body.
Other solutions are registering to a scroll event and re-setting the position everytime. This results in poor performance on mobile.

How to slide in element like other element drag it out?

I use AngularJS.
I need to make next things:
When I click 'Fade in' - the hidden element should appear (slide out) from left side. But it should slide behind 'MAIN BASE' element and it should look like DRAGGER drags it out from left to right. How to implement it? any ideas?
.base {
height: 50px;
width: 300px;
border: 1px solid blue;
}
.faded {
border: 1px solid greenyellow;
width: 200px;
}
.dragger {
height: 50px;
width: 100%;
border: 1px solid green;
}
.fade.ng-enter {
transition: 0.9s linear all;
width: 0;
}
.fade.ng-enter.ng-enter-active {
width: 100%;
}
<div layout="row">
<div class="base">MAIN BASE</div>
<div ng-if="bool" class=" faded fade"> Hidden element </div>
<div class="dragger">DRAGGER</div>
</div>
<button ng-click="bool=true">Fade In!</button>
<button ng-click="bool=false">Fade Out!</button>
Solved. used:
.animation('.slide', ['$animateCss', function($animateCss) {
return {
enter: function(element) {
return $animateCss(element, {
event: 'enter',
structural: true,
from: { 'margin-left': -300},
to: { 'margin-left': 0},
duration: 0.3
});
}
}
}])
<div layout="row">
<div class="base">MAIN BASE</div>
<div ng-if="bool" class=" faded slide"> Hidden element </div>
<div class="dragger">DRAGGER</div>
</div>
<button ng-click="bool=true">Fade In!</button>
<button ng-click="bool=false">Fade Out!</button>

How to do centered <h1> with <hr/> on both sides over a background image

How do I create centered <h1> with <hr/> on both sides over a background image?
I also need it to handle various text lengths, scale well for mobile viewing and have the <hr/> go to 100% width of its container.
I want this look, but over a background image.
There are lots of answers (here, here here and here) for text with lines on either side but all of them rely on using a solid background colour behind the text, which doesn't work for me as the page I want to put this on has a background image.
Here is how I achieve the look above, which handles various lengths of text and scales well:
CSS
.title-box {
height: 2px;
background-color: rgb(215, 0, 0);
text-align: center;
}
.title-outer {
background-color:rgb(230, 230, 230);
position: relative;
top: -0.7em;
}
.title-inner {
margin:0px 20px;
font-size: 17.5px;
font-weight:bold;
color:rgb(100, 100, 100);
}
HTML
<div class="title-box">
<span class="title-outer">
<span class="title-inner">OUR STORY</span>
</span>
</div>
I have tried the method below and it kind of works but it doesn't handle various text widths or scale well due to the <h1> and the <hr/>s being in seperate <div>s:
HTML
<div class="row">
<div class="span4"><hr /></div>
<div class="span4"><h4>OUR STORY</h4></div>
<div class="span4"><hr /></div>
</div>
Note: This is example is using the Bootstrap grid system but that is not part of the problem/solution.
So any ideas how I can get the same look and behaviour but without the backgound colour for the text so it can sit over a background image?
No need JS, here is a pure CSS solution.
CSS
.title-hr hr {
display: inline-block;
width: 30%;
margin: 5px 10px;
border-top: 1px solid #e5e5e5;
}
HTML
<h1 class="title-hr"><hr />My Title<hr /></h5>
Result: http://jsfiddle.net/yptmftr4/
Ok, I've played a bit with this code and here is my solution. Yes, it's a bit dirty because I've used :before and :after, but works.
HTML
<div class="title-box">
<span id="first" class="title-inner">OUR LOOOoo oooo oOONG STORY</span>
</div>
<div class="title-box">
<span id="second" class="title-inner">OUR STORY</span>
</div>
<div class="title-box">
<span id="third" class="title-inner">STORY</span>
</div>
CSS
.title-box {
text-align: center;
}
.title-inner {
margin:0px 20px;
font-size: 17.5px;
font-weight:bold;
position: relative;
color:rgb(100, 100, 100);
}
.title-inner:after, .title-inner:before {
content:"";
float: right;
position: relative;
top: 8px;
height: 2px;
background: red;
}
.title-inner:before {
float: left;
}
jQuery
$(document).ready(function () {
function work() {
$(".title-inner").each(function () {
var full_width = $(window).width();
var id = $(this).attr("id");
var title_width = $("#" + id).width();
var new_width = (full_width - title_width) / 2 - 40;
$('head').append("<style>#" + id + ":before, #" + id + ":after{width:" + new_width + "px !important;}</style>");
});
}
work();
$(window).resize(function () {
work();
});
});
http://jsfiddle.net/ffb3X/4/
Because :before and :after are not part of DOM, I've used .append() function to append style tags in head for every title.
This code will on page load calculate everything, so it's responsive.
This code was posted originally by Arbel but his/her answer disappeared for some reason? I am reposting it (including some mods I've made) because it was the solution I ended up using. Credit where credit is due.
Working jsFiddle: http://jsfiddle.net/pA5Gu/
HTML
<div class="title-box">
<fieldset class="title-outer">
<legend id="titleInner" class="title-inner">OUR STORY</legend>
</fieldset>
</div>
CSS
.title-box {
background-image: url('http://imagezo.com/images/1302-green-bubbles-awesome-background-wallpaper.jpg');
height:100%;
}
.title-outer {
border-top:2px solid rgb(215, 0, 0);
background-color: transparent;
}
.title-inner {
width:auto;
padding:0px 20px;
border: 0;
background-color: transparent;
font-size: 17.5px;
font-weight:bold;
color:rgb(255, 255, 255);
}
jQuery
$(document).ready(function() {
var legendWidth = $('#titleInner').outerWidth();
var margin = 'calc((100% - '+legendWidth+'px) / 2)';
$('#titleInner').css('margin-left', margin);
$('#titleInner').css('margin-right', margin);
});
http://jsfiddle.net/habo/HrfuH/1/
<div class="title-box">
<div class="myContent">
<div class="title-outer"><hr /></div>
<div class="title-inner "><h4>OUR STORY</h4></div>
<div class="title-outer"><hr /></div>
</div>
</div>
.myContent{
display:block;
width:600px;
margin:0 auto;
}
.title-box {
background:#eee;
height:60px;
}
.title-outer{
}
hr {
height: 2px;
background-color:rgb(215, 0, 0);
margin: 2em 0;
width:25%;
float:left;
}
.title-inner {
margin:0px 20px;
font-size: 17.5px;
font-weight:bold;
color:rgb(100, 100, 100);
float:left;
}