To achieve center alignment for both texts, a simple positioning technique using position: absolute
can be employed and applied to the texts. By positioning the texts relative to the center anchor, they can be centered effectively as shown:
var app = new Vue({
el: "#app",
data: {
solved: false,
},
methods: {
change_solved() {
this.solved = !this.solved;
},
},
})
.container {
position: relative;
}
.cat_num {
transition: all 2s ease;
position: absolute;
right: 50%;
top: 0;
transform: translate(0, 0);
}
.cat_num.active {
font-size: 40px;
top: 100px;
transform: translate(50%, 0);
text-align: center;
}
.cat_name {
transition: all 2s;
position: absolute;
left: 50%;
top: 0;
transform: translate(0, 0);
}
.cat_name.active {
font-size: 50px;
top: 200px;
transform: translate(-50%, 0);
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button v-on:click="change_solved">Solve</button>
<div class="container">
<h1 class="cat_num" :class="{active : solved}">Text 1</h1>
<h1 class="cat_name" :class="{active : solved}">Text 2 (possibly lengthy)</h1>
</div>
</div>
The issue with the lengthy text arises when it extends beyond a single line, impacting the smoothness of the transition due to changes in text alignment (using text-align: left
or text-align: center
). To address this problem, an edit was made as follows:
var app = new Vue({
el: "#app",
data: {
solved: false,
},
methods: {
change_solved() {
this.solved = !this.solved;
},
},
})
.container {
position: relative;
text-align: center;
}
.cat_num {
transition: all 2s ease;
right: 50%;
top: 0;
transform: translate(0, 0);
display: inline;
position: static;
}
.cat_num.active {
font-size: 40px;
top: 100px;
transform: translate(50%, 0);
text-align: center;
position: absolute;
}
.cat_name {
transition: all 2s;
left: 50%;
top: 0;
transform: translate(0, 0);
display: inline;
position: static;
}
.cat_name.active {
font-size: 50px;
top: 200px;
transform: translate(-50%, 0);
text-align: center;
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js</script>
<div id="app">
<button v-on:click="change_solved">Solve</button>
<div class="container">
<h1 class="cat_num" :class="{active : solved}">Text 1</h1>
<h1 class="cat_name" :class="{active : solved}">Text 2 (possibly lengthy)</h1>
</div>
</div>
However, transitioning between states with this method may result in a sudden jump to the middle. This occurs due to changes in the position
property. To resolve this issue, a JavaScript workaround involving the calculation of left
and right
values while maintaining position: absolute
is recommended:
var app = new Vue({
el: "#app",
data: {
solved: false,
isMounted: false,
},
computed: {
textsTotalWidth() {
if (!this.isMounted) {
return 0
}
return (this.$refs.catNum.offsetWidth + this.$refs.catName.offsetWidth) / 2
},
catNumRight() {
if (!this.isMounted) {
return ''
}
return `calc(50% + ${this.textsTotalWidth - this.$refs.catNum.offsetWidth}px)`
},
catNameLeft() {
if (!this.isMounted) {
return ''
}
return `calc(50% - ${this.textsTotalWidth - this.$refs.catNum.offsetWidth}px)`
}
},
methods: {
change_solved() {
this.solved = !this.solved;
},
},
mounted() {
this.isMounted = true;
}
})
.container {
position: relative;
}
.cat_num {
transition: all 2s ease;
position: absolute;
top: 0;
transform: translate(0, 0);
}
.cat_name.active {
font-size: 50px;
top: 200px;
transform: translate(-50%, 0);
text-align: center;
left: 50% !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js></script>
<div id="app">
<button v-on:click="change_solved">Solve</button>
<div class="container">
<h1 ref="catNum" class="cat_num" :class="{active : solved}" :style="{'right':catNumRight}">Text 1</h1>
<h1 ref="catName" class="cat_name" :class="{active : solved}" :style="{'left':catNameLeft}">Text 2 (possibly lengthy)</h1>
</div>
</div>