How to implement ::v-deep on Sass suffixes (&__) selector in Vue2? - sass

I am working on scoping all the styles of our Vue2 frontend codebase to prepare for the transition into Vue3. I have read on Vue docs that the ::v-deep directive enables the child component to receive the scoped styles from their parent components.
We use Sass. Some child component classes don't get the style applied even though I have implemented ::v-deep on their parent component.
Here's the code of the style section:
<style lang="scss" scoped>
.support-category::v-deep {
.icon-back {
font-size: 14px;
color: color(text4);
}
.border-bottom {
border-bottom: 1px solid color(bg3);
}
&__subject {
font-size: 18px;
font-weight: 700;
}
&__accordion {
font-size: 15px;
ul,
ol {
margin-bottom: 0.75rem;
margin-left: 14px;
margin-top: 3px;
}
ul {
list-style-type: disc;
}
ol {
list-style-type: decimal;
}
}
}
</style>
Here's the portion of code of the template section:
<div v-if="hasSupportCategories">
<div
v-for="category in mainSupportCategory.support_categories"
:key="category.id"
class="mb-8"
>
<v-row>
<v-col :size="12">
<v-accordion
class="support-category__accordion"
:initial-active="mainSupportCategory.support_categories.length === 1"
>
<template v-slot:title>
<div class="support-category__subject pb-3 border-bottom">
{{ category.title }}
</div>
</template>
<div
v-for="item in category.support_items"
:key="item.id"
>
<v-accordion class="support-category__accordion border-bottom py-3">
<template v-slot:title>
<div class="font-bold">
{{ item.title }}
</div>
</template>
<v-markdown
:source="item.text"
class="pt-3 pb-2"
/>
</v-accordion>
</div>
</v-accordion>
</v-col>
</v-row>
</div>
</div>
The v-accordion component has ::v-deep implemented as well:
<style lang="scss" scoped>
.accordion::v-deep {
.icon-left {
margin-right: 0.75rem;
font-size: 12px;
color: color(text4);
}
}
</style>
<div class="accordion flex flex-col w-full">
<div
class="cursor-pointer"
#click="toggle"
>
<slot name="title" />
</div>
<div v-show="active">
<slot />
</div>
</div>
I have tried many techniques but nothing worked out:
&::v-deep(__subject) {
font-size: 18px;
font-weight: 700;
}
or
&::v-deep(&__subject) {
font-size: 18px;
font-weight: 700;
}
The only solution that worked is to make this suffixe selector an independent child selector.
.subject {
font-size: 18px;
font-weight: 700;
}
That works for this case but since we use suffixes a lot in the codebase I would like to find a solid solution.
Thanks!

Answer:
Use a postcss.config.js file and add a 'postcss-prefix-selector' like so to give each class a prefix.
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
'postcss-prefix-selector': {
prefix: '#single-spa-application',
},
},
};

Related

Svelte - Transitions in layout not delaying {#key}ed <slot> update

I'm trying to add a transition between pages in a SvelteKit application. When navigating, the current page should fade out, and the new page should then fade in in its place. To accomplish this, in +layout.svelte, I wrapped the <slot> in a div with the in and out transitions set. I wrapped this all in {#key $page.url.pathname} so that the animations are triggered when navigating from page to page. However, my current code produces this effect:
When navigating, the content of the page updates before fading out. In other words, the destination page immediately appears, then fades out, then fades back in. At the same time, though, content in +layout.svelte (.title, at the top of the page) behaves correctly; just the content within the <slot> is bugged.
Here is the code:
+layout.svelte
<script lang="ts">
import '$lib/style.css';
import { page } from '$app/stores';
import { fade } from 'svelte/transition';
</script>
<div class="page">
<div class="bar">
Sidebar
Page 1
Page 2
</div>
<div class="content-wrapper">
{#key $page.url.pathname}
<div class="content" in:fade={{ delay: 1000, duration: 1000 }} out:fade={{ duration: 1000 }}>
<div class="title">
{$page.url.pathname}
</div>
<slot />
</div>
{/key}
</div>
</div>
<style global>
.page {
display: flex;
flex-direction: row;
box-sizing: border-box;
width: 100vw;
min-height: 100vh;
}
.bar {
display: flex;
flex-direction: column;
width: 300px;
color: white;
background: black;
}
a {
color: white;
}
.content-wrapper {
flex-grow: 1;
width: 100%;
min-height: 100vh;
}
.content {
width: 100%;
height: 100%;
}
.title {
font-size: 2em;
}
</style>
+page.svelte
<div class="page">
<div class="title">Page 1</div>
</div>
<style>
.page {
width: 100%;
height: 100%;
background: blue;
}
</style>
page2/+page.svelte
<div class="page">
<div class="title">Page 2</div>
</div>
<style>
.page {
width: 100%;
height: 100%;
background: red;
}
</style>
Is there a way to get the <slot> content to wait for the out animation to finish before updating?
Its an issue with the lifecycle of the transitions for in and out.
I usually use in:fade ONLY on elements and it looks okay. It seems using both means that while one element is going out, another is coming in at the same time in which looks funny.
Perhaps you could find out more about delay in transitions and let us know..
Happy coding☺️

Responsive side-by-side images with overlay text when hovering

I'd like to have a header and then three images side-by-side.
When in small screens, the images should occupy all the width and be placed vertically one after another.
For each image, when the mouse is over it, some text should be overlayed.
For mobile and touch screens, I don't know how that text could be shown, but would like to have it shown in some way.
Each of the images should point to another html page (not shown in my example.
What I managed to do until now is:
<!DOCTYPE html>
<html>
<head>
<style>
html {
font-family: helvetica, arial, sans-serif;
}
.cabecalho {
width:70%;
height:200px;
text-align:center;
margin:70px;
margin-top:10px;
}
.cabecalho p{
line-height: 10px; /* within paragraph */
margin-bottom: 4px; /* between paragraphs */
}
.corpo {
width:60%;
height:500px;
}
* {
box-sizing: border-box;
}
.img__description_layer {
position: relative;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(204, 204, 204, 0.6);
color: #111;
visibility: hidden;
opacity: 0;
display: flex;
align-items: center;
justify-content: center;
pad: 8px;
height: 300px;
width: 200px;
/* transition effect. not necessary */
transition: opacity .2s, visibility .2s;
}
.img__description {
transition: .2s;
transform: translateY(1em);
}
.img__wrap:hover .img__description {
transform: translateY(0);
}
.img__wrap:hover .img__description_layer {
visibility: visible;
opacity: 1;
}
.column {
float: left;
width: 33.33%;
padding: 5px;
}
/* Clearfix (clear floats) */
.row::after {
content: "";
clear: both;
display: table;
}
/* Responsive layout - makes the three columns stack on top of each other instead of next to each other */
#media screen and (max-width: 500px) {
.column {
width: 100%;
}
}
</style>
</style>
</head>
<body>
<div class="cabecalho">
<header>
</header>
</div>
<main>
<div class="row">
<div class="column">
<div class="img__wrap">
<img class="img__img" alt="alttext" align="middle" src="http://placehold.it/257x200.jpg" width="300" height="200" style="width:100%">
<div class="img__description_layer">
<p class="img__description">Some paragraph</p>
</div>
</div>
</div>
<div class="column">
<div class="img__wrap">
<img class="img__img" alt="alttext" align="middle" src="http://placehold.it/257x200.jpg" width="300" height="200" style="width=100%">
<div class="img__description_layer">
<p class="img__description">Some paragraph</p>
</div>
</div>
</div>
<div class="column">
<div class="img__wrap">
<img class="img__img" alt="alttext" align="middle" src="http://placehold.it/257x200.jpg" width="300" height="200" style="width=100%">
<div class="img__description_layer">
<p class="img__description">Some paragraph</p>
</div>
</div>
</div>
</div>
</main>
</body>
</html>
I'd appreciate some help on this.

Laravel8 webpack vue extractstyle output selector is something strange

i'm before using vue(v2, cli) and laravel(for api server).
in this case, i want to use laravel8 with vue2.
so i'm setting laravel with vue. and i want to use vue component style tag.
my vue component like this
<template>
<header class="nav__header">
<div class="nav__header-wrapper">
<div class="nav__top">
<div class="nav__top-content">
</div>
</div>
<div class="nav__menu-wrapper">
<div class="nav__menu-logo">
caravan
</div>
<div class="nav__menu-area-wrapper">
<nav class="nav__menu-area">
<ul class="nav__menu">
<li>caravan</li>
<li>
sub menu
<ul class="nav__menu-sub">
<li>
sub
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</div>
</header>
</template>
<script>
export default {
name: 'Nav',
}
</script>
<style lang="scss">
.nav__header {
content: '';
background-color: #fff;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, .5);
.nav__header-wrapper{
max-width: 1140px;
margin: auto;
box-sizing: border-box;
outline: 0;
padding: 0;
.nav__top{
background-color: #232323;
position: relative;
z-index: 2;
font-size: .8em;
line-height: 42px;
&:before{
display: block;
content: ' ';
position: absolute;
top: 0;
bottom: 0;
left: -2000em;
right: -2000em;
background-color: #232323;
border-top: 1px solid rgba(0,0,0,.1);
}
&:after{
content: ' ';
display: table;
width: 100%;
clear: both;
}
}
}
#media (max-width: 1199px) {
.nav__header-wrapper{
width: 100%;
max-width: none;
padding: 0 30px;
}
}
}
</style>
my laravel-mix set like this.
mix.js('resources/js/app.js', 'public/js')
.vue({
version: 2,
extractStyles: true,
globalStyles: false
})
.sass('resources/sass/app.scss', 'public/css')
i try to change version and extractStyles to file path. but output css always like this
enter image description here
css selectors always strange(is that hashed?)
anybody know this issue?

Vue Animation Individual floating elements like on Coachella website

Can anyone point out how to achieve something similar to
https://www.coachella.com/home/
Social section animation/carousel
Can someone point out how we may create it in a Vue object with the help of transitions and more..
HTML
<template>
<div id="app">
<div class="cent">
<button v-on:click="show = !show">Toggle</button>
</div>
<div class="cent">
<transition v-for="block in blocks" :key="block" name="fade">
<div class="block" v-if="show">
<p class="els">{{block}}</p>
</div>
</transition>
</div>
</div>
</template>
JS
export default {
name: "app",
data() {
return {
msg: "Welcome to Your Vue.js App",
show: false,
blocks: ["element", "fire", "water", "earth", "wind"]
};
}
};
CSS
.els{
background-color: aqua;
display: inline-flex;
padding:20px;
}
.cent{
margin-left:auto;
margin-right:auto;
display: flex;
justify-content: center;
flex-direction: column;
overflow: hidden;
}
.block {
font-family: Arial, Helvetica, sans-serif;
color: #fff;
flex-basis: auto;
}
.fade-enter{
}
.fade-enter-active{
animation:slideIn 1s ease-out forwards;
}
.fade-leave{
}
.fade-leave-active{
animation:slideOut 1s ease-out forwards;
}
#keyframes slideIn {
from {
transform:translateX(100%);
}
to {
transform:translateX(0%);
}
}
#keyframes slideOut {
from {
transform:translateX(0%);
}
to {
transform:translateX(100%);
}
}
Just a basic try to make elements of blocks float... But as said earlier i want to make it float like coachella site.
P.S
I have tried google and other resources like madewithvuejs and others but didn't found anything similar.
Any help would be grateful..

Connect jQuery UI nested sortable items

I'm trying to connect multiple nested items using jQuery UI's sortable.
The code is correctly selecting draggable/droppable items, but selected items cannot be nested elsewhere.
How should I allow connecting (nesting) in all weblog-sections and item-body elements?
<!DOCTYPE html>
<html html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Sortable with jQuery test</title>
<style>#myToolTip {
display: none;
}
.Mainheading {
font-size: 2em;
color: red;
}
.weblog {
width: 65%;
padding: 5px;
margin: 10px;
font-family: monospace;
}
.weblog-section {
background-color: #EEE;
margin-bottom: 10px;
}
.item-body {
/*background-color: #EEE; */
}
div {
border-radius: 5px;
-webkit-border-radius: 5px;
border: 1px #CCC dashed;
margin: 3px;
padding: 5px 5px;
}
OL {
counter-reset: item;
margin: 1px;
padding: 5px;
font-weight: bolder;
}
LI {
display: block;
font-size: 1.1em;
padding: 5px 10px;
background-color: #DDD;
margin: 1px;
border-radius: 5px;
-webkit-border-radius: 5px;
font-family: Tahoma;
}
LI:before { content: counters(item, ".") " "; counter-increment: item }
p {
padding: 0px 5px;
text-align:justify;
}
.toolbox, .toolbar:link{
color:white;
font-size: smaller;
font-family: monospace;
text-decoration:none;
}
#sortable { }
#sortable li { margin: 0 5px 5px 5px; padding: 5px; font-size: 1.2em; height: 1.5em; }
html>body #sortable li { height: 1.5em; line-height: 1.2em; }
.ui-state-highlight { height: 1.5em; line-height: 1.2em; }</style>
</head>
<body>
<ol>
<div class="weblog">
<div class="weblog-section">
<li>Some blog title</li>
<div class="item-body">
<p>Some blog text.</p>
</div>
</div>
<div class="weblog-section">
<li>Some blog title</li>
<div class="item-body">
<p>Some blog text.</p>
</div>
</div>
<div class="weblog-section">
<li>Some blog title</li>
<div class="item-body">
<!--<p></p>-->
<ol>
<div class="weblog-section">
<li>Some blog title</li>
<div class="item-body">
<p>Some blog text.</p>
</div>
</div>
</ol>
</div>
</div>
<div class="weblog-section">
<li>Some blog title</li>
<div class="item-body">
<p>Some blog text.</p>
</div>
</div>
</div>
</ol>
<script type="text/javascript" src='scripts/jquery-3.2.1.js'></script>
<script type="text/javascript" src="scripts/jquery-ui.js"></script>
<script>
$( function() {
$( ".weblog-section" ).sortable({
connectWith: ".weblog-section",
items: ".item-body"
});
$( ".weblog-section" ).disableSelection();
$( ".weblog" ).sortable({
connectWith: " > .item-body",
items: "> .weblog-section",
});
$( ".weblog" ).disableSelection();
} );
</script>
</body>
</html>
If you run the code, you would recognise what's missing. Sortable is working fine on the inner items. But It's not possible to drag a weblog-title and put it under another section.
For some reason I couldn't figure out the logic I should use to write the right jquery script.
Whatever I tried, I ended up getting parent-child errors.
Cheers
The functionality you are looking for is not built into jQuery UI's Sortable.
I would like to suggest for you to look at https://github.com/ilikenwf/nestedSortable, as it has been the chosen answer in jQuery Nested Sortable - Move LI elements within all available UL's.

Resources