Vue- How to change style of a same element in different components - html

I am trying to change the style of a specific div from one component to another. Each component is appended to the template in the App component and replaces the <router-view></router-view> tags. The div #app needs to have a padding of 172px in the Hello.vue component, and 0px on the rest of the components.Is this possible, and how can I accomplish this?
App.vue
<template>
<div id="app">
<div>
<img src="./assets/logo.png" align="center">
</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
background-color: hsla(275, 97%, 50%, 0.57);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 0px;
height: inherit;
}
body{
height: inherit;
}
html{
height: 100%;
}
</style>
Hello.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<ul>
<li><h2><router-link to="/app/login">Login</router-link></h2></li>
<li><h2><router-link to="/app/about">About Us</router-link></h2></li>
</ul>
</div>
</template>
<script>
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Vue'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#app{
padding-top: 172px; /*This does not work*/
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #000000;
}
</style>

There is a quick way to do this (not sure if it's best practice) by checking the route path; assume Hello.vue is rendered via the path /hello:
<div id="app" :style="{ padding: $route.path === '/hello' ? '172px' : '0px' }">
...
</div>

Related

How to open a vuejs data in a new page using a button?

I got the data from an API and managed to get the HTML text converted but I would like to open it in a new tab using a #button?
How can I do that?
<li v-for="(item, index) in paginated('items')" :key="index" class="flex-item">
<div id="article" v-html="item.details_en" target="blank">Explore More</div>
I need an explore more button to get a new tab and to see the item.details_en
You can achieve when click Explore more button the details should be in new page with explore details using router concept .
Step 1: Install vue-router npm package
npm install --save vue-router
Step 2: Add router reference in main.js
import Vue from "vue";
import App from "./App.vue";
import router from "#/router";
import VuePaginate from "vue-paginate";
Vue.use(VuePaginate);
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App)
}).$mount("#app");
Step 3: Create view components Home.vue and Explore.vue under views folder
Home.vue
<template>
<div>
<paginate ref="paginator" class="flex-container" name="items" :list="items">
<li v-for="(item, index) in paginated('items')"
:key="index"
class="flex-item">
<h4>{{ item.pub_date }}, {{ item.title }}</h4>
<img :src="item.image && item.image.file" />
<div class="downloads">
<span v-for="downloadable in item.downloadable.filter(
(d) => !!d.document_en)" :key="downloadable.id">
<a :href="downloadable.document_en.file">Download</a>
</span>
</div>
<button type="button" id="article" #click.prevent="exploremore(item)">
Explore More
</button>
</li>
</paginate>
<paginate-links
for="items"
:limit="2"
:show-step-links="true"
></paginate-links>
</div>
</template>
<script>
import axios from "axios";
import router from "#/router";
export default {
data() {
return {
items: [],
paginate: ["items"],
};
},
created() {
this.loadPressRelease();
},
methods: {
loadPressRelease() {
axios
.get(
`https://zbeta2.mykuwaitnet.net/backend/en/api/v2/media-center/press-release/?page_size=61&type=5`
)
.then((response) => {
console.log(response.data.results);
this.items = response.data.results;
});
},
exploremore(item) {
console.log("item", item);
router.push({
name: "explore",
params: { details: JSON.stringify(item.details_en) },
});
},
},
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
ul.flex-container {
padding: 0;
margin: 0;
list-style-type: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-direction: row wrap;
flex-wrap: wrap;
justify-content: space-around;
}
li img {
display: initial;
height: 100px;
}
.flex-item {
background: tomato;
width: calc(100% / 3.5);
padding: 5px;
height: auto;
margin-top: 10px;
color: white;
font-weight: bold;
text-align: center;
}
.downloads {
margin-top: 10px;
}
ul.paginate-links.items li {
display: inline-block;
margin: 5px;
}
ul.paginate-links.items a {
cursor: pointer;
}
ul.paginate-links.items li.active a {
font-weight: bold;
}
ul.paginate-links.items li.next:before {
content: " | ";
margin-right: 13px;
color: #ddd;
}
ul.paginate-links.items li.disabled a {
color: #ccc;
cursor: no-drop;
}
</style>
Explore.vue
<template>
<div>
<div v-html="details" />
</div>
</template>
<script>
export default {
name: "expore",
props: ["details"],
};
</script>
Step 4: Add router-view in app.vue
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "App",
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
DEMO

How to make make a margin-bottom in the headline?

The following code snippet shows my wished position for my headline in the footer.
* {
box-sizing: border-box;
}
/*HEADER*/
.header{
overflow: hidden;
height: 91px;
background-color: #000000;
width: 100%;
}
.header a {
color: #34E034;
text-decoration: none;
}
.header a.logo {
font-family: Wiz;
font-size: 55px;
font-weight: bold;
}
html, body {
margin:0;
padding:0;
}
<div class = "header">
<div class="header-row">
<div class="left-main-header">
<div class="header-box">
<div class="new-header">Techwizards</div>
<a class="logo"><b>Techwizards</b></a>
</div>
</div>
</div>
</div>
If I now wanna add a font style for the headline. This one:
#font-face {
src: url("fonts/MagicSchoolTwo.ttf");
font-family: wiz;
}
I don't have margin to the bottom like in this picture.
I tried everything - margin, padding but I don't get the space to the bottom. How can I fix that?
Fixed Your Code:
You had an absolute height on your header. Then an "a" tag can't have a margin on default, you have to set it on display block to render the margin. I also added display flex to your header as suggested in the comments.
Codepen
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
/*HEADER*/
.header {
background-color: #000000;
width: 100%;
display: flex;
}
.header a {
color: #34e034;
text-decoration: none;
}
.header a.logo {
font-family: Wiz;
font-size: 55px;
font-weight: bold;
display: block;
margin-bottom: 40px;
}
<div class="header">
<div class="header-row">
<div class="left-main-header">
<div class="header-box">
<div class="new-header">Techwizards</div>
<a class="logo"><b>Techwizards</b></a>
</div>
</div>
</div>
</div>

How to pass an image with props in vuejs without all the content disappearing when there's no image?

I have a component that in some cases will receive an image and in others it won't. So, I want this component to work in both ways. But, when it doesn't have any image, the other contents of this component, including styles doesn't work, they disappear. Is there a way that I can do this?
App.Vue:
<template>
<div id="app" class="raleway">
<link href='https://fonts.googleapis.com/css?family=Raleway' rel='stylesheet'>
<section class="title">
<Title name='Title' filename="twitter"/>
</section>
</div>
</template>
<script>
import Title from "./components/Title.vue";
export default {
name: "App",
components: {
Title,
},
};
</script>
<style>
html,
body {
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: #3B3B3B;
font-family: 'Raleway';
}
.title{
margin-top: 8em;
}
</style>
Component:
<template>
<div class="background">
<div class="title">
<h2><img :src="require(`#/assets/${filename}.svg`)" class="img">{{name}}</h2>
</div>
</div>
</template>
<script>
export default {
name: 'Background',
props:{
name: String,
filename: String,
}
}
</script>
<style scoped>
*{
margin: 0;
padding: 0;
}
.background{
background-color: #3B3B3B;
}
.title{
border: 1px solid #707070;
border-left: none;
border-right: none;
}
.title h2{
text-align: left;
color: #B16DFF;
padding-top: 0.5em;
font-size: 2em;
padding-bottom: 0.5em;
margin-left: 1.5em;
font-weight: 600;
}
.img{
padding-right: 1em;
}
#media(max-width: 580px){
.title h2{
font-size: 1.17em;
}
}
</style>
You could use v-if to conditionally render the <img> based on whether filename is truthy:
<img v-if="filename" :src="require(`#/assets/${filename}.svg`)">
I would pass in the image reference as a computed property, not requiring it directly in the source.
Then in the template you could use v-if to check if that was present, and render a 'no image' message using v-else if no image data present

CSS Variable trough Polymer (dynamically loaded) elements

I have multiple custom elements in my projects and I have a problem with css variables. In my parent element I have multiple item element with status classes. I want to manipulate the background and border color using that status classes, but I want to define the values in my parent element but somehow it not want to work.
Here my parent element:
<link rel="import" href="app-task.html" />
<dom-module id="app-task-grid">
<template>
<style>
:host {
display: block; position: absolute; left: 0; top: 0; width: 100%; height: 100%;
overflow:hidden; background: #eee;
--column-1-width: 80px;
--column-3-width: 120px;
--column-4-width: 180px;
--column-5-width: 220px;
--column-6-width: 100px;
--task-background-color: #eee;
--task-border-color: #ccc;
}
:host table.header {
position: absolute; top: 0; left: 0; width: 100%; height: 40px; background: #DDD;
}
:host table.header th {
letter-spacing: 2px; font-weight: normal; text-transform: uppercase;
font-size: 80%; border-left: 1px solid #aaa;
margin: 0; padding: 0 10px;
}
:host th.column1 {
width: var(--column-1-width);
}
:host th.column2 {
text-align: left;
}
:host th.column3 {
width: var(--column-3-width);
}
:host th.column4 {
width: var(--column-4-width);
}
:host th.column5 {
width: var(--column-5-width);
}
:host th.column6 {
width: var(--column-6-width);
text-align: left;
}
:host th.hide, :host td.hide {
display: none;
}
:host th.show, :host td.show {
display: table-cell;
}
:host table.header .scrollbar {
width: 20px; border-left: none;
padding: 0;
}
:host .items {
position: absolute; left: 0; top: 40px; right: 0; bottom: 0;
overflow:hidden; overflow-y: scroll;
margin: 0; padding: 0;
}
:host .items::-webkit-scrollbar {
width:22px; border-left: 6px solid #ddd;
background-color:#ddd;
}
:host .items::-webkit-scrollbar-thumb {
background-color:#aaa;
border-left: 6px solid #ddd;
min-height: 80px;
}
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<table class="header">
<tr>
<th class="column1"></th>
<th class="column2">Column#2</th>
<th class="column3">Column#3</th>
<th class="column4">Column#4</th>
<th class="column5">Column#5</th>
<th class="column6">Column#6</th>
<th class="scrollbar"></th>
</tr>
</table>
<div class="items">
<app-task id="task0" class="waiting"></app-task>
</div>
</template>
<script>
Polymer({
is:"app-task-grid",
loadItems: function()
{
let statuses = ['waiting','assigned','started','working','aborted'];
for(var i = 1; i<=30; i++)
{
let itemStatus = statuses[Math.floor(Math.random()*statuses.length)];
let itemElement = document.createElement('APP-TASK');
itemElement.id = 'task'+i;
itemElement.classList.add(itemStatus);
console.debug( itemElement );
this.querySelector('.items').appendChild( itemElement );
}
}
});
</script>
</dom-module>
My children element:
<dom-module id="app-task">
<template>
<style>
:host {
display: block; margin: 8px 0; padding: 0;
}
:host table {
width: 100%; height: 80px;
background-color: var(--task-background-color, #fff);
border-bottom: 5px solid var(--task-background-color, #fff);
border-top: 5px solid var(--task-background-color, #fff);
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.07),
0 1px 5px 0 rgba(0, 0, 0, 0.06),
0 3px 1px -2px rgba(0, 0, 0, 0.1);
}
:host table td {
border-left: 1px solid var(--task-border-color, #ccc);
margin: 0; padding: 0 10px;
}
:host td.column1 {
width: var(--column-1-width);
}
:host td.column2 {
}
:host td.column3 {
width: var(--column-3-width);
}
:host td.column4 {
width: var(--column-4-width);
}
:host td.column5 {
width: var(--column-5-width);
}
:host td.column6 {
width: var(--column-6-width);
}
</style>
<table>
<tr>
<td class="column1">C#1</td>
<td class="column2">C#2</td>
<td class="column3">C#3</td>
<td class="column4">C#4</td>
<td class="column5">C#5</td>
<td class="column6">C#6</td>
</tr>
</table>
</template>
<script>
Polymer({
is:"app-task"
});
</script>
</dom-module>
I tried already:
:host .waiting { ... }
:host app-task.waiting { ... }
app-task.waiting { ... }
:root .waiting { ... }
:root app-task.waiting { ... }
:root { .waiting { ... } }
:root { app-task.waiting { ... } }
parent element for the app-task for the classes
style is="custom-style" inside the app-grid template
style is="custom-style" outside the template but inside the app-grid element html file
but none of them seems working.
If I define the css variables in the :host then it's working, only not working with classes somehow. Where did made a mistake?
UPDATE#1:
Something weird hapening with the style-scope, if I add the "style-scope app-task-grid" to the parent element for the tasks:
<div class="items">
<div class="style-scope app-task-grid waiting">
<app-task id="task1"></app-task>
</div>
</div>
then if I add a normal css rule like a color its applied in the app-task, but the css variables are not.
UPDATE#2:
As it was mention that this template is working, and I tested it and it is, !But id did not mention that the items are created on the fly and appended to the items. I added almost everything from my code on Plunker: http://plnkr.co/edit/b5XW1w3sEOy4UHc0rdWH?p=preview
Sorry about my mislead, I did not know that the problem source was the dynamic load.
Note: I updated the question with more example.
UPDATE#3:
Thanks to #a1626s and #GünterZöchbauer we found the answer:
My initial code was good and worked from the beginning, I defined the questions badly becasue I did not see what was the problem. So if somebody dynamically load elements inside an element must use Polymer.dom api.
Polymer.dom(this.querySelector('.items')).appendCild(itemElement);
I don't see any problem in your initial code. I copied your code and pasted it in plunker
<style>
:host {
display: block;
}
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
and it seemed to be working fine for me.
As for your new problem replace your javascript method with this method and it should work.
{
let statuses = ['waiting','assigned','started','working','aborted'];
for(var i = 1; i<=30; i++)
{
let itemStatus = statuses[Math.floor(Math.random()*statuses.length)];
let itemElement = document.createElement('APP-TASK');
itemElement.id = 'task'+i;
itemElement.classList.add(itemStatus);
console.debug( itemElement );
Polymer.dom(this.$.items).appendChild(itemElement);
}
Polymer.dom.flush();
}
Also, here is the change that i made in your app-task-grid element
<div class="items" id="items"> //added id attribute to the div tag
The problem being the way you are adding child elements they do not get properly inserted into dom tree of the element. Polymer has documentation on how to work with tree of its elements. You can read more about it here
Remember that the <style> where the CSS variables are set must have is="custom-style" in the tag.
I've thrown together a very crude snippet to show it.
<script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://polygit.org/components/polymer/polymer.html">
<dom-module id="app-task">
<template>
<style>
:host {
display: block;
height: 80px;
margin: 5px;
background-color: var(--task-background-color, #fff);
border: 1px solid var(--task-border-color, #ccc);
}
</style>
<div>some stuff...</div>
</template>
<script>
Polymer({
is: 'app-task'
});
</script>
</dom-module>
<!-- Beginning of the 'parent element' -->
<style is="custom-style">
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
Another example with it running through several elements
<script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://polygit.org/components/polymer/polymer.html">
<dom-module id="app-task">
<template>
<style>
:host {
display: block;
height: 80px;
margin: 5px;
background-color: var(--task-background-color, #fff);
border: 1px solid var(--task-border-color, #ccc);
}
</style>
<div>some stuff...</div>
</template>
<script>
Polymer({
is: 'app-task'
});
</script>
</dom-module>
<!-- Beginning of the 'parent element' -->
<dom-module id="app-task-grid">
<template>
<!-- normal styles -->
<style>
app-task {
width: 50%;
margin: 10px auto;
}
</style>
<!-- custom styles -->
<style is="custom-style">
.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}
.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}
.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}
.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}
.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>
<div class="items">
<app-task id="task1" class="waiting"></app-task>
<app-task id="task2" class="waiting"></app-task>
<app-task id="task3" class="working"></app-task>
<app-task id="task4" class="working"></app-task>
<app-task id="task5" class="assigned"></app-task>
<app-task id="task6" class="aborted"></app-task>
</div>
</template>
<script>
Polymer({
is: 'app-task-grid'
});
</script>
</dom-module>
<!-- And now pushing it to the screen -->
<app-task-grid></app-task-grid>

HTML text color of my button isn't coming out correctly

I'm a n00b, so go easy on me. :)
Right now I'm stuck because I need to figure out why the text color of the two named buttons (Resume and Programs) isn't white. The buttons reside inside divs of class outerdiv; thus they should inherit the property font-color: #FFFFFF. But apparently they aren't doing that, since the font is still black.
Please explain the HTML logic that corrects this problem.
Code:
<html>
<head>
<title>my site</title>
<style type="text/css">
p
{
font-family: Arial;
color: #FFFFFF;
}
#mtx_bckgd
{
font-family: "Courier New";
height: 750px;
width: 1000px;
position: absolute;
z-index: -1;
background: linear-gradient(180deg, #39275b, #FFFFFF);
}
#mtx_bckgd > p
{
word-wrap: break-word;
color: #D8D8D8;
overflow: hidden;
}
#headerbox
{
height: 50px;
top: 25px;
left: 5px;
}
h1
{
color: #FFFFFF;
font-weight: 400;
text-align: center;
margin: auto;
padding: auto;
text-shadow: 2px 2px rgb(51,51,51);
}
#navbar
{
top: 120px;
left: 5px;
width: 1000px;
height: 30px;
}
#uwlogo
{
height: 50px;
float: left;
}
#JaminWEB
{
margin: 0px auto;
}
.navbutton
{
width: 33%;
height: 25px;
background-color: rgba(51,51,51,0.5);
margin: 0px;
padding: 0px;
}
#footer
{
top: 800px;
}
.outerdiv
{
position: absolute;
font-family: Arial;
width: 1000px;
border: solid 2px #FFFFFF;
background-color: rgba(215,169,0,0.5);
margin: 0px;
padding: 0px;
font-color: #FFFFFF;
}
</style>
<script type="text/javascript">
function change_bckgd()
{
var bitstr = "";
for (var i = 0; i < 4000; ++i)
bitstr += Math.floor(Math.random() * 10) % 2 ? "0" : "1";
document.getElementById("mtx_txt").innerHTML = bitstr;
}
</script>
</head>
<body>
<div id="mtx_bckgd">
<p id="mtx_txt"></p>
</div>
<div class="outerdiv" id="headerbox">
<div id="uwlogo">
<img src="C:\Users\XXXXXX\Desktop\uwlogo.png" height="50px">
</div>
<div id="JaminWEB">
<h1>JaminWEB</h1>
</div>
</div>
<div class="outerdiv" id="navbar">
<input type="button" class="navbutton" value="Resume"/>
<input type="button" class="navbutton" value="Programs"/>
<input type="button" class="navbutton"/>
<div class="outerdiv" id="footer">
<p>Last modified: March 21st, 2014</p>
</div>
<script type="text/javascript">
setInterval(change_bckgd, 200);
</script>
</body>
</html>
First, in your .outer-div rules, you have font-color which isn't a property, it's just color. But if you correct that, you'll see the text is still black, the default color. That's because browsers are notorious for having issues when rendering form controls.
As the MDN says:
CSS font and text features can be used easily with any widget (and
yes, you can use #font-face with form widgets). However, browsers'
behaviors are often inconsistent. By default, some widgets do not
inherit font-family and font-size from their parents. And many
browsers use the system default appearance instead.
The easiest way to fix this would be to add color:inherit; or color:white to your .navbutton class
jsFiddle example
.outerdiv input[type=button]
{
color:#fff;
}
You can set .navbutton to have a color of white in the css, or adding color:inherit should work. And the proper "font-color" property in CSS is just "color", fyi.
Example:
.navbutton
{
width: 33%;
height: 25px;
background-color: rgba(51,51,51,0.5);
margin: 0px;
padding: 0px;
color: #fff;
}
Inputs don't automatically inherit all parent styles, so you have to specify to inherit, or specify the style you want.