How to make a custom Web Component "height:100%" of the page? - javascript

I wrote a Web Component using Vue.js and vue-custom-element. Now I want to make my-chat and my-whiteboard Web Components "height:100%".I'm using the component like this:
// App.vue
<template>
<splitpanes class="default-theme">
<pane>
<my-chat></my-chat>
</pane>
<pane>
<my-whiteboard></my-whiteboard>
</pane>
</splitpanes>
</template>
The only way that I know is to set the height of all parents to 100% like this:
html,
body,
splitpanes,
pane,
my-chat,
my-whiteboard {
height: 100%;
}
//main.js
...
// Load custom element plugin
Vue.use(vueCustomElement);
// Define web components
Vue.customElement("skyroom-whiteboard", Whiteboard);
Vue.customElement("skyroom-chat", Chat);
...
And do this for the all tags inside web my-chat and my-whiteboard too!!!
The problems:
This is not working for my- components.
It seems to be wrong! Isn't there any right way to do this?

The simple way to do it is to use
my-chat, my-whiteboard {
min-height: 100vh;
}
However, when one of them becomes taller than 100vh, it will grow without the other one. So, most likely, ...
display: block;
height: 100vh;
overflow-y: auto;
... will do a better job.
Here's an example (you don't need any the CSS after /* let's test it */ line but I had to add it as all of them are custom elements and, by default, they have a display value of inline):
my-chat,
my-whiteboard {
display: block;
height: 100vh;
overflow-y: auto;
}
/* let's check it */
my-chat,
my-whiteboard {
box-sizing: border-box;
}
tester {
height: 200vh;
padding: 1rem;
}
splitpanes { display: flex; }
pane:first-child { flex-basis: 75%; }
pane:last-child { flex-grow: 1; }
body { margin: 0; }
/* don't use this line in your app, it will likely break stuff
* I used it here because I don't have any content to break! */
.default-theme * { display: block; }
<splitpanes class="default-theme">
<pane>
<my-chat>
<tester>my-chat</tester>
</my-chat>
</pane>
<pane>
<my-whiteboard>
<tester>my-whiteboard</tester>
</my-whiteboard>
</pane>
</splitpanes>
Important note: If any of your components gets parsed by Vue into actual <div> elements, you'll need to change the selectors accordingly (but you did say they're custom elements, so I'm guessing they're used as-is).

Related

How to change a css value in javascript?

So I want to change a css value in javascript, without having an element in html, I'll explain like:
<style>
.box{
width: 10%;
}
</style>
<script>
// I want to change the width value of (.box) to something like "90%"
</script>
So what I mean to say is that I want to change the (.box) width value between the two style tags, I know my question sounds weird, but am just new coding and I really need it, any help appreciated!
Use media queries.
I don't remember the exact way to do this, but something like:
.box { width: 90%; }
#media screen and (min-width: 1000px) {
.box { width: 40%; }
}
You can change the properties (e.g. width) of a CSSStyleDeclaration with its setProperty() method.
You can get a CSSStyleSheet of a specific <style> element with its sheet property.
In our case, the stylesheet's first CSSStyleRule (sheet.cssRules[0]) is for the CSS class .box. You get the CSSStyleDeclaration object of a CSSStyleRule with its style property.
Example:
const iClass = document.getElementById("i-class");
const classRule = document.getElementById("my-style").sheet.cssRules[0];
// Set input.value to initial width-value (10%)
iClass.value = classRule.style.getPropertyValue("width");
// Update width-value on each input
iClass.addEventListener("input", () => {
classRule.style.setProperty("width", iClass.value);
});
/* Ignore; presentational styling */
.box {
margin-bottom: .5rem;
aspect-ratio: 1/1;
background-color: coral;
text-align: center;
}
<style id="my-style">
.box{
width: 10%;
}
</style>
<div>
<label for="i-class">Class width:</label> <input id="i-class">
</div>
<div class="box">class</div>
Unlike adding a new CSS rule, this changes the existing rule.
Here's one option, adding a <style> tag dynamically. This will add a style which overrides previous, obviously. See other answers for other options of changing existing rules.
var inline_style = `
.box {
width: 90%;
background: pink;
}`;
// from https://stackoverflow.com/a/28662118/3807365
document.head.insertAdjacentHTML("beforeend", '<style>' + inline_style + '</style>')
.box {
width: 10%;
background: blue;
}
<div class="box">i'm a box</div>

Change css class attribute values using javascript

I want to change the value of one of the attributes of css class dynamically
Here's my scenario:
I've many elements using one class, instead of getting them all and looping them over and applying style, I want to change the value of one of the attributes of class, which is alredy applied on them. for example
.prodName {
max-width: 270px;
display: block;
}
above class is being used by many elements, and I want to alter one of the attributes of that class like
.prodName {
max-width: 350px <---
display: block;
}
is there any simple method for this in javascript.
Before I post this question, I already searched but didn't find anything easy and useful.
thanks in advance to helping hands.
You can use CSS variables for this case.
const root = document.querySelector(':root');
function play() {
root.style.setProperty('--size', '300px');
}
:root {
--size: 100px;
}
.container {
background-color: red;
width: var(--size);
height: var(--size);
cursor: pointer;
}
<div class="container" onclick="play()"></div>
The only problem with the above approach is support in older browsers. If you have to support IE, and older browsers where CSS variable support is not present, you can handle this problem by adding a class to the body/parent container.
function play() {
document.body.classList.add('large')
}
.container {
background-color: red;
width: 100px;
height: 100px;
cursor: pointer;
}
.large .container {
width: 300px;
height: 300px;
}
<div class="container" onclick="play()"></div>
Add new class to CSS:
.mw350 {
max-width: 350px;
}
Then add new class to the element in JS:
document.querySelector('.prodName').className += ' mw350'; // <-- better to select using unique IDs, like '#prodNameElement'
If you are going to control the css class/attribute change from ts, maybe with a function or var change, you might want to use ngClass: https://www.freecodecamp.org/news/angular-ngclass-example/ and have all the logic where you want it, easily accessible.

Using dark or light mode

what is the best way to incorporate something like this into my site? I've tried using plugins but I cant get it to work. Doesn't have to be fancy.
Does anyone have it or have used one in the past they can recommend? Otherwise, is there a way to code it using JavaScript?
You could just set a button to trigger a boolean for example and based on its values, change the background-color of the items you want to change into dark mode.
I personally used react context for this one, something like this (kinda perfect how they used theme as an example). You should study it.
It depends on your framework, but if you use Material-UI, it has this option.
you can change palette type from light to dark and vice versa to achieve your requirements. Take a look here.
But if you don't use any framework, you should make a css structure that has two classes, light and dark, have some properties like color and background color and etc., and when the toggle theme button clicked, you will change all your classes from light to dark for example, also you can use animation for the effects.
There is a multiple solutions for this problem, if you are using a specific framework I suggest you check if there a way to do it with it, if you are not using any framework you still have multiple solutions and I suggest to create for each element you want to change his properties to dark mode another CSS class for each one, and with JavaScript create a function (that can call by a button on the html) that change all the element you want to those external classes, and if you click this button once again is reverse the function and make all the classes be with the original CSS classes
Maybe this should help you to kickstart.
<html class="theme-light">
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.theme-light {
--color-primary: #0060df;
--color-secondary: #fbfbfe;
--color-accent: #fd6f53;
--font-color: #000000;
}
.theme-dark {
--color-primary: #17ed90;
--color-secondary: #243133;
--color-accent: #12cdea;
--font-color: #ffffff;
}
.container {
display: flex;
width: 100%;
height: 100%;
background: var(--color-secondary);
flex-direction: column;
justify-content: center;
align-items: center;
}
.container h1 {
color: var(--font-color);
}
.container button {
color: var(--font-color);
background: var(--color-primary);
padding: 10px 20px;
border: 0;
border-radius: 5px;
}
</style>
<script>
// Set a Theme
function setTheme(themeName) {
localStorage.setItem('theme', themeName);
document.documentElement.className = themeName;
}
// Toggle From light and dark theme and Vice-Versa
function toggleTheme() {
if (localStorage.getItem('theme') === 'theme-dark') {
setTheme('theme-light');
} else {
setTheme('theme-dark');
}
}
// Onload Theme
(function() {
if (localStorage.getItem('theme') === 'theme-dark') {
setTheme('theme-dark');
} else {
setTheme('theme-light');
}
})();
</script>
<body>
<div class="container">
<h1>Theme Switcher</h1>
<button id="switch" onclick="toggleTheme()">Switch Theme</button>
</div>
</body>
</html>
This is a simple approach that I've used several times:
On the main html file, I load the default theme, for example the light one:
<link rel="stylesheet" href="/themes/light/theme.css" id="linkTheme" />
Then, on the theme changer button/menu option, I change the CSS file of the above link to load the corresponding one, something like:
const handleToggleTheme = (dark) => {
const lightUrl = "/themes/light/theme.css";
const darkUrl = "/themes/dark/theme.css";
if (dark) {
document.getElementById('linkTheme').setAttribute('href', darkUrl);
}
else {
document.getElementById('linkTheme').setAttribute('href', lightUrl);
}
}

JS Sapper + Bulma breakpoints in (S)CSS

I'm trying to use Sapper with Bulma and (S)CSS.
My goal is to apply various paddings on "main" inside of src/routes/layout.html, with padding on desktop devicees, and without (or a smaller one) on mobile.
Using the predefined breakpoints or mixins doesn't work properly for me, as the following code raises an SCSS error :
EDIT: this is the svelte component:
<script>
import 'bulma/css/bulma.css'
// or import 'bulma/bulma.sass' ???
</script>
<style type="text/scss">
main {
position: relative;
max-width: 56em;
background-color: white;
margin: 0 auto;
sizing: border-box;
padding: 0.5em;
+desktop-only {
padding: 2em;
}
}
</style>
What's wrong and how to fix it ?

Create and Display a Div using JQuery without distorting other elements

I am trying to create a div and show a timeout message in there. But it actually distorts other parts of Page. For eg see below. Session Timed out is the div with the message.
Now I don't want this to happen. PFB the JQuery code I am using to create this Div
function ShowSessionTimeOutDiv() {
var styler = document.createElement("div");
styler.setAttribute("style","font-size:15px;width:auto;height:auto;top:50%;left:40%;color:red;");
styler.innerHTML = "<b><i>Session TimedOut, Please refresh the Page</i></b>";
document.body.appendChild(styler);
var currentDiv = $('#GoToRequestControl1_UpdatePanel1').get(0);
currentDiv.parentNode.insertBefore(styler,currentDiv) ;
}
Am I missing something here? The Part in which this div is being displayed is coming from Master Page.
Have you tried the position:fixed styling on it in css, i did that on one of my websites and it didn't distort anything.
A page has a natural flow of its elements based on the default display rules specified by the W3C. When you add a div in between other elements it naturally affects the layout of the page; the positions of the other elements.
In order to drop in a new element without it affecting other elements you have to either reserve space for it, or take it out of the normal page flow.
There are a couple of ways to take an element out of the flow — you can float it, float:left or float:right, which is great, for example, to stack blocks on the left (instead of top-down) and let them wrap to new rows as available width changes. Using a flex layout gives you a lot of control also. But in this case of one thing popping up, changing the positioning of the new element is the most straightforward and can let you put the block exactly where you want it.
I have a demonstration and full explanation in a fiddle showing several examples along the way to getting what you want.
Basically, styling is needed to reposition the timeout message element that you're inserting. Styling is better done with CSS styles, compared to adding a bunch of inline styles. If I put my timeout popup message in a "messagebox" I can make a class for it.
/* Your styles, plus a couple extra to make the example stand out better */
div.messagebox {
font-size: 16px;
width: auto;
height: auto;
top: 40%;
left: 30%;
background-color: white;
border: 2px solid black;
}
Likewise, style the message itself with a class, instead of using inline styles and the deprecated presentational tags <b> and <i>.
/* I want the message in a messagebox to be bold-italic-red text. */
div.messagebox .message {
color: red;
font-style: italic;
font-weight: bold;
}
The big difference is that we will change the positioning of the element from the default static to instead use absolute positioning:
/* I don't really recommend a class called "positioned".
A class should describe the kind of thing the element *is*
not how it *looks*
*/
div.messagebox.positioned {
position: absolute;
width: 40%;
padding: 1.5em;
}
/* The container of the positioned element also has to be positioned.
We position it "relative" but don't move it from its natural position.
*/
section#hasposition {
position: relative;
}
The term "absolute" is tricky to learn ... the element being positioned is given an absolute position within its container, in a sense it's positioned relative to its container... but what position:relative means is relative to its own natural position, so it's easy to get confused at first over whether you want absolute or relative positioning.
Putting it all together, we have some basic HTML that represents major portions of a page — a real page will have far more, but those should be contained within some top-level containers. This shows only those top-level containers.
Then we have some javascript that will add the new element at the appropriate time. Here I just call the function to add it after a delay created with setTimeout(). I'm using full-on jQuery since you're using some in your example, and it makes the javascript more portable and more concise.
function ShowSessionTimeoutStyled() {
var styler = $('<div>').addClass('messagebox').addClass('positioned');
styler.html('<span class="message">The Session Timed Out</span>');
$('#hasposition .above').after(styler);
}
// wait 6 seconds then add the new div
setTimeout(ShowSessionTimeoutStyled, 6000);
div.messagebox {
font-size: 16px;
width: auto;
height: auto;
top: 20%;
left: 20%;
background-color: white;
border: 2px solid black;
}
div.messagebox .message {
color: red;
font-style: italic;
font-weight: bold;
}
div.messagebox.positioned {
position: absolute;
width: 40%;
padding: 1.5em;
}
section#hasposition {
position: relative;
}
/* also style some of the basic parts so you can see them better in the demonstration */
section.explanation {
margin: 1em 0.5em;
padding: 0.5em;
border: 1px solid gray;
}
.demonstration {
margin-left: 1em;
padding: 1em;
background-color: #e0e0e0;
}
.demonstration .above {
background-color: #fff0f0;
}
.demonstration .middle {
background-color: #f0fff0;
}
.demonstration .below {
background-color: #f0f0ff;
}
.demonstration footer {
background-color: white;
}
p {
margin-top: 0;
padding-top: 0;
}
section {
font-family: sans-serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="explanation">
<p>Here, a div is added dynamically, after the "basic part above", but the added div is <em>positioned</em>. You can see the other content isn't affected.</p>
<section class="demonstration" id="hasposition">
<div class="above">Basic part above</div>
<div class="middle">Middle part</div>
<div class="below">Part Below</div>
<footer>This is the page footer</footer>
</section>
</section>
I highly recommend the site Position Is Everything for articles and tutorials on positioning. Some of its other content is outdated — who needs to make PNGs to do drop-shadows any more? — but the way positioning works hasn't changed.

Categories