WordPress × Wavesurfer JS — finally got around to sharing my experience using wavesurfer.js in conjunction with a WordPress site.

When I was making the second version of my website and decided to update the music section I wanted to make a player with frequency chart visualization like SoundCloud. I quickly found wavesurfer.js and then began the process of gathering information from different sites on how to use it. Gradually I came to the desired result and decided to share it, maybe it will be useful for beginners like me.
Wavesurfer.js is an open source audio visualization library for creating interactive, customizable waveforms.
I made a WordPress page template that you can select when you create the page and put the script itself, the layout, and the additional features I wanted in it.
A list of options that are in my example:
- Audio player as a whole
- Frequency chart visualization
- Search by track (by clicking on the frequency chart)
- Total time and elapsed time of a track
- Cover image
- Play /pause button (icon on the button changes)
- Volume control
- mute button
- Music styles in tag format
- Buy link button
- Icons-links to music platforms
- Track description and lyrics
Check out the example player page on my site.

Next I will try to detail the features of the web development I did.
Here is the source code of the WordPress page template with the Wavesurfer JS player and additional features.
Let me clarify right away that I’m using version 6.6.3 of the wavesurfer.js script and hosting it locally on my web server. This is not the latest version, you can find it on GitHub of the project
<?php
/* Template Name: Music - Single */
get_header();
get_sidebar();
?>
<div class="music-single-container">
<div class="audio-player-container-wraper">
<div class="audio-player-container">
<div class="play-track-name">
<div id="playButton" class="play-button">
<img
id="playButtonIcon"
class="play-button-icon"
src="<?php echo get_template_directory_uri(); ?>/img/icons/play-thin.svg"
alt="Play Button"
/>
</div>
<h1 class="track-name"><?php the_title(); ?></h1>
<p class="music-style post-category-main"><?php echo the_tags('',' ',''); ?></p>
</div>
<div id="waveform" class="waveform">
<div id="loading_flag">
<!-- content set by JS -->
</div>
</div>
<span id="currentTime">00:00:00</span>
<span id="totalDuration">00:00:00</span>
<div class="volume-group">
<div class="volume-button">
<img
id="volumeIcon"
class="volume-icon"
src="<?php echo get_template_directory_uri(); ?>/img/icons/speaker-high-thin.svg"
alt="Volume"
/>
</div>
<input
id="volumeSlider"
class="volume-slider"
type="range"
name="volume-slider"
min="0"
max="100"
value="50"
aria-label="Volume"
/>
</div>
<a data-lightbox="post-image" class="music-single-cover" href="<?php echo get_the_post_thumbnail_url( get_the_id(), 'full' ); ?>">
<img src="<?php echo get_the_post_thumbnail_url( get_the_id(), 'medium' ); ?>" alt="<? the_title(); ?>" >
</a>
</div>
</div>
<div class="buy-streaming-wraper">
<div class="buy-streaming-container">
<div class="buy">
<a class="wp-block-button__link wp-element-button" href="<?php echo get_post_meta($post->ID, '%mp3_Buy', true); ?>" target="_blank"><?php include'img/icons/buy-thin.php'; ?>
<?php
$networksiteid = get_current_blog_id();
if( $networksiteid == 1 ){
echo "Купить";
} else {
echo "Buy";
}
?>
</a>
</div>
<div class="streaming">
<a class="streaming-link" id="streaming-link-vk-music" href="<?php echo get_post_meta($post->ID, '%VK_Music_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-vk-music-01.svg" alt="VK Музыка иконка логотип" class="wp-image-6869"></a>
<a class="streaming-link" id="streaming-link-ya-music" href="<?php echo get_post_meta($post->ID, '%Yandex_Music_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-ya-music-01.svg" alt="Яндекс Музыка иконка логотип" class="wp-image-6867"></a>
<a class="streaming-link" id="streaming-link-promo-dj" href="<?php echo get_post_meta($post->ID, '%Promo_DJ_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/05/social-media-icons-svg-promo-dj-01.svg" alt="PromoDJ иконка логотип" class="wp-image-6867"></a>
<a class="streaming-link" id="streaming-link-soundcloud" href="<?php echo get_post_meta($post->ID, '%Soundcloud_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-soundcloud-01.svg" alt="Soundcloud иконка логотип" class="wp-image-6871"></a>
<a class="streaming-link" id="streaming-link-bandcamp" href="<?php echo get_post_meta($post->ID, '%Bandcamp_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-bandcamp-01.svg" alt="Bandcamp иконка логотип" class="wp-image-8002"></a>
<a class="streaming-link" id="streaming-link-beatport" href="<?php echo get_post_meta($post->ID, '%Beatport_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-beatport-01.svg" alt="Beatport иконка логотип" class="wp-image-8161"></a>
<a class="streaming-link" id="streaming-link-apple-music" href="<?php echo get_post_meta($post->ID, '%Apple_Music_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-apple-01.svg" alt="Apple Music иконка логотип" class="wp-image-7120"></a>
<a class="streaming-link" id="streaming-link-spotify" href="<?php echo get_post_meta($post->ID, '%Spotify_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-spotify-01.svg" alt="Spotify иконка логотип" class="wp-image-8010"></a>
<a class="streaming-link" id="streaming-link-youtube" href="<?php echo get_post_meta($post->ID, '%YouTube_Music_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/02/social-media-icons-svg-youtube-01.svg" alt="YouTube Music иконка логотип" class="wp-image-6842"></a>
<a class="streaming-link" id="streaming-link-amazon" href="<?php echo get_post_meta($post->ID, '%Amazon_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-amazon-music-01.svg" alt="Amazon Music иконка логотип" class="wp-image-8009"></a>
<a class="streaming-link" id="streaming-link-deezer" href="<?php echo get_post_meta($post->ID, '%Deezer_link', true); ?>" target="_blank"><img decoding="async" src="https://tiku.ru/wp-content/uploads/2023/03/social-media-icons-svg-deezer-01.svg" alt="Deezer иконка логотип" class="wp-image-8008"></a>
</div>
</div>
</div>
<div class="music-single-desc">
<p><?php include'template-parts/likes-views.php'; ?> </p>
<?php the_content(); ?>
<p class="work-year"><?php the_date('j F Y'); ?></p>
<?php
include'template-parts/share.php';
include'template-parts/author.php';
?>
<p><?php include'template-parts/next-post.php'; ?></p>
<p><?php include'template-parts/tags.php'; ?></p>
</div>
</div>
<?php
include'template-parts/similar-pages.php';
?>
<?php if ( comments_open() ) { ?>
<div class="page-container width-940">
<div class="page-content-container">
<div><?php comments_template(); ?></div>
</div>
</div>
<?php } ?>
<?php
get_footer();
?>
<?php
$musicfile = get_post_meta($post->ID, '%mp3_URL', true);
$pcm = get_post_meta($post->ID, '%pcm', true);
?>
<script src="<?php echo get_template_directory_uri(); ?>/js/wavesurfer.js"></script>
<script>
/* utiluty functions */
const playButton = document.querySelector("#playButton")
const playButtonIcon = document.querySelector("#playButtonIcon")
const waveform = document.querySelector("#waveform")
const volumeIcon = document.querySelector("#volumeIcon")
const volumeSlider = document.querySelector("#volumeSlider")
const currentTime = document.querySelector("#currentTime")
const totalDuration = document.querySelector("#totalDuration")
// --------------------------------------------------------- //
/**
* Initialize Wavesurfer
* @returns a new Wavesurfer instance
*/
const initializeWavesurfer = () => {
return WaveSurfer.create({
backend: "MediaElement",
container: "#waveform",
responsive: true,
height: 80,
waveColor: "#9999ff",
progressColor: "#3300ff",
barWidth: 2,
barHeight: 1,
barGap: 2,
barRadius: 2,
})
}
// --------------------------------------------------------- //
// Functions
/**
* Toggle play button
*/
const togglePlay = () => {
wavesurfer.playPause()
const isPlaying = wavesurfer.isPlaying()
if (isPlaying) {
playButtonIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/pause-thin.svg"
} else {
playButtonIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/play-thin.svg"
}
}
/**
* Handles changing the volume slider input
* @param {event} e
*/
const handleVolumeChange = e => {
// Set volume as input value divided by 100
// NB: Wavesurfer only excepts volume value between 0 - 1
const volume = e.target.value / 100
wavesurfer.setVolume(volume)
// Save the value to local storage so it persists between page reloads
localStorage.setItem("audio-player-volume", volume)
}
/**
* Retrieves the volume value from local storage and sets the volume slider
*/
const setVolumeFromLocalStorage = () => {
// Retrieves the volume from local storage, or falls back to default value of 50
const volume = localStorage.getItem("audio-player-volume") * 100 || 50
volumeSlider.value = volume
}
/**
* Formats time as HH:MM:SS
* @param {number} seconds
* @returns time as HH:MM:SS
*/
const formatTimecode = seconds => {
return new Date(seconds * 1000).toISOString().substr(11, 8)
}
/**
* Toggles mute/unmute of the Wavesurfer volume
* Also changes the volume icon and disables the volume slider
*/
const toggleMute = () => {
wavesurfer.toggleMute()
const isMuted = wavesurfer.getMute()
if (isMuted) {
volumeIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/speaker-x-thin.svg"
volumeSlider.disabled = true
} else {
volumeSlider.disabled = false
volumeIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/speaker-high-thin.svg"
}
}
// --------------------------------------------------------- //
// Create a new instance and load the wavesurfer
const wavesurfer = initializeWavesurfer()
var musicFile = '<?php echo $musicfile; ?>'
var pcm = <?php echo $pcm; ?>;
wavesurfer.load(musicFile, pcm)
// --------------------------------------------------------- //
// Javascript Event listeners
window.addEventListener("load", setVolumeFromLocalStorage)
playButton.addEventListener("click", togglePlay)
volumeIcon.addEventListener("click", toggleMute)
volumeSlider.addEventListener("input", handleVolumeChange)
// --------------------------------------------------------- //
// Wavesurfer event listeners
wavesurfer.on("ready", () => {
// Set wavesurfer volume
wavesurfer.setVolume(volumeSlider.value / 100)
// Set audio track total duration
const duration = wavesurfer.getDuration()
totalDuration.innerHTML = formatTimecode(duration)
})
// Sets the timecode current timestamp as audio plays
wavesurfer.on("audioprocess", () => {
const time = wavesurfer.getCurrentTime()
currentTime.innerHTML = formatTimecode(time)
})
// Resets the play button icon after audio ends
wavesurfer.on("finish", () => {
playButtonIcon.src = "https://tiku.ru/wp-content/themes/Tiku/img/icons/play-thin.svg"
})
function UpdateLoadingFlag(Percentage) {
if (document.getElementById("loading_flag")) {
document.getElementById("loading_flag").innerText = "Загрузка " + Percentage + "%";
if (Percentage >= 100) {1
document.getElementById("loading_flag").style.display = "none";
} else {
document.getElementById("loading_flag").style.display = "block";
}
}
}
// show progress while loading sound
wavesurfer.on('loading', function(X, evt) {
UpdateLoadingFlag(X);
});
// clean up etc., when wavesurfer fires the "ready" event
wavesurfer.on('ready', function() {
console.log("ready fired");
});
document.getElementById("sun").onclick = function() {lightToDark()};
function lightToDark() {
wavesurfer.setWaveColor('#ff9999');
wavesurfer.setProgressColor('#ff6666');
}
document.getElementById("moon").onclick = function() {darkToLigh()};
function darkToLigh() {
wavesurfer.setWaveColor('#9999ff');
wavesurfer.setProgressColor('#3300ff');
}
if (document.getElementById("theme-link").href === "https://tiku.ru/wp-content/themes/Tiku/css/dark.css" || document.getElementById("theme-link").href === "https://tiku.ru/en/wp-content/themes/Tiku/css/dark.css") {
wavesurfer.setWaveColor('#ff9999');
wavesurfer.setProgressColor('#ff6666');
} else {
wavesurfer.setWaveColor('#9999ff');
wavesurfer.setProgressColor('#3300ff');
}
if(document.getElementById("streaming-link-amazon").getAttribute("href")!=="") {
document.getElementById("streaming-link-amazon").style.display = "inline-block";
}
if(document.getElementById("streaming-link-vk-music").getAttribute("href")!=="") {
document.getElementById("streaming-link-vk-music").style.display = "inline-block";
}
if(document.getElementById("streaming-link-ya-music").getAttribute("href")!=="") {
document.getElementById("streaming-link-ya-music").style.display = "inline-block";
}
if(document.getElementById("streaming-link-soundcloud").getAttribute("href")!=="") {
document.getElementById("streaming-link-soundcloud").style.display = "inline-block";
}
if(document.getElementById("streaming-link-bandcamp").getAttribute("href")!=="") {
document.getElementById("streaming-link-bandcamp").style.display = "inline-block";
}
if(document.getElementById("streaming-link-beatport").getAttribute("href")!=="") {
document.getElementById("streaming-link-beatport").style.display = "inline-block";
}
if(document.getElementById("streaming-link-apple-music").getAttribute("href")!=="") {
document.getElementById("streaming-link-apple-music").style.display = "inline-block";
}
if(document.getElementById("streaming-link-spotify").getAttribute("href")!=="") {
document.getElementById("streaming-link-spotify").style.display = "inline-block";
}
if(document.getElementById("streaming-link-youtube").getAttribute("href")!=="") {
document.getElementById("streaming-link-youtube").style.display = "inline-block";
}
if(document.getElementById("streaming-link-deezer").getAttribute("href")!=="") {
document.getElementById("streaming-link-deezer").style.display = "inline-block";
}
if(document.getElementById("streaming-link-promo-dj").getAttribute("href")!=="") {
document.getElementById("streaming-link-promo-dj").style.display = "inline-block";
}
/*
wavesurfer.on('waveform-ready', () => {
wavesurfer.exportPCM(1024, 10000, false);
})
*/
</script>
WordPress × Wavesurfer JS: description of the solution
In the following, I will try to describe the components of the solution in detail.
I actively used arbitrary WordPress fields, for example to get URL for .mp3 file or PCM data to build a sound wave visualization.
In this part of the code, variables are created to which data from arbitrary WordPress fields are written.
<?php
$musicfile = get_post_meta($post->ID, '%mp3_URL', true);
$pcm = get_post_meta($post->ID, '%pcm', true);
?>
This is what it looks like in the WordPress admin:

This block of code configures the wavesurfer itself, for example how the wave visualization will look like:
const initializeWavesurfer = () => {
return WaveSurfer.create({
backend: "MediaElement",
container: "#waveform",
responsive: true,
height: 80,
waveColor: "#9999ff",
progressColor: "#3300ff",
barWidth: 2,
barHeight: 1,
barGap: 2,
barRadius: 2,
})
}
This block of code is where the .mp3 file and PCM data is connected for fast rendering of the visualization (more on this later):
// --------------------------------------------------------- //
// Create a new instance and load the wavesurfer
const wavesurfer = initializeWavesurfer()
var musicFile = '<?php echo $musicfile; ?>'
var pcm = <?php echo $pcm; ?>;
wavesurfer.load(musicFile, pcm)
Next is an important point, which I finished after the first run. One of the problems was that the sound wave visualization was displayed only after the audio file was fully loaded (you can see the markup and the load indication script in the code). This often took a significant amount of time for music tracks, and when I decided to post DJ mixes as well, the problem became very serious — long loading times.
I already knew that this could be solved by specifying PCM data in advance, but I didn’t know how to get that data. In the end this piece of code helps to do it:
/*
wavesurfer.on('waveform-ready', () => {
wavesurfer.exportPCM(1024, 10000, false);
})
*/
It is commented out as it is only required when posting a new track. The process is a bit crooked, but it works for me personally:
First I disable the PCM data right here:
Was:
wavesurfer.load(musicFile, pcm)
It’s become:
wavesurfer.load(musicFile)
After that, the player starts working in audio loading mode to build a visualization of the sound wave. I also remove the comment markings from this code:
wavesurfer.on('waveform-ready', () => {
wavesurfer.exportPCM(1024, 10000, false);
})
I fill in all the other information that the template requires and start the preview of the WordPress page, the track loading indication starts and after its completion a new browser tab is automatically opened, which contains the PCM data.
Next, I simply copy them and paste them into an arbitrary WordPress field for that page. Next I need to return the PCM data in the code:
wavesurfer.load(musicFile, pcm)
And comment out that block of code:
/*
wavesurfer.on('waveform-ready', () => {
wavesurfer.exportPCM(1024, 10000, false);
})
*/
After that, the visualization is displayed instantly.
Support my website
The CSS styles look like this and I think comments on them are unnecessary. But if you have any questions, please post in the comments, I’ll try to help.
/* Audio Player */
.music-single-container {
}
.music-single-desc {
margin: 0 auto;
max-width: 1600px;
padding: 2%;
}
.audio-player-container {
display: grid;
gap: 0;
grid-template-areas:
"play-track-name play-track-name volume-group cover"
"wave wave wave cover"
"currentTime currentTime totalDuration cover";
grid-template-rows: repeat(3, auto);
grid-template-columns: repeat(4, 1fr);
column-gap: 2%;
row-gap: 0;
justify-items: stretch;
align-items: start;
justify-content: space-evenly;
align-content: space-evenly;
padding: 2%;
margin: 0 auto;
max-width: 1920px;
background: linear-gradient(#eee, #fff);
}
.audio-player-container-wraper {
background: linear-gradient(#eee, #fff);
}
.music-single-cover, .music-single-cover:hover {
grid-area: cover;
width: 100%;
border: 0;
}
.music-single-cover img {
width: 100%;
height: auto;
aspect-ratio: 1 / 1;
box-shadow: var(--shadow-elevation-medium);
}
.play-track-name {
grid-area: play-track-name;
display: grid;
gap: 0;
grid-template-areas:
"play-pause track-name"
"play-pause track-name"
"play-pause music-style";
grid-template-rows: repeat(3, auto);
grid-template-columns: 80px auto;
column-gap: 2%;
row-gap: 0;
align-self : center;
}
.play-track-name h1, .play-track-name .music-style {
margin: 8px 0;
padding: 0;
line-height: 1.3;
}
.track-name {
grid-area: track-name;
text-align: start;
align-self : end;
}
.music-style {
grid-area: music-style;
}
.play-button {
grid-area: play-pause;
align-self : center;
width: 80px;
height: 80px;
padding: 20px;
}
#loading_flag {
padding: 25px 0;
text-align: center;
background: url(../img/icons/waveform-thin.svg) center center;
color: var(--accent-color);
font-weight: bold;
display: none;
}
#waveform {
height: 120px;
}
.play-button-icon, .volume-icon {
width: 100%;
height: auto;
aspect-ratio: 1 / 1;
}
.play-button, .volume-button {
background: var(--accent-color);
line-height: 0;
margin: 0;
border-radius: 50%;
cursor: pointer;
transition: 0.2s linear;
}
.play-button:hover, .volume-button:hover {
background: #3300cc;
transform: scale(1.1);
}
.volume-group {
grid-area: volume-group;
display: grid;
gap: 0;
grid-template-areas:
"volume-button volume-slider";
grid-template-rows: repeat(1, auto);
grid-template-columns: repeat(2, auto);
column-gap: 20px;
row-gap: 0;
justify-items: stretch;
align-items: start;
justify-content: space-evenly;
align-content: space-evenly;
align-self : center;
justify-self: end;
}
.volume-button {
grid-area: volume-button;
align-self : center;
width: 40px;
height: 40px;
padding: 8px;
}
.volume-slider {
grid-area: volume-slider;
align-self : center;
}
#currentTime {
grid-area: currentTime;
color: #999;
}
#totalDuration {
grid-area: totalDuration;
justify-self: end;
color: #999;
}
#waveform {
grid-area: wave;
align-self : end;
padding: 20px 0;
border-radius: 8px;
}
wave{
overflow-x: hidden!important;
border: 0!important;
cursor: pointer!important;
}
@media only screen and (max-width: 940px) {
.audio-player-container {
padding: 8vw 4vw;
display: grid;
gap: 0;
grid-template-areas:
"cover cover cover cover"
"play-track-name play-track-name play-track-name play-track-name"
"wave wave wave wave"
"currentTime volume-group volume-group totalDuration";
grid-template-rows: repeat(4, auto);
grid-template-columns: repeat(4, 1fr);
column-gap: 2%;
row-gap: 2%;
justify-items: stretch;
align-items: start;
justify-content: space-evenly;
align-content: space-evenly;
}
#currentTime, #totalDuration {
align-self : center;
font-size: 0.8em;
}
.volume-group {
column-gap: 2vw;
justify-self: center;
padding: 20px 0;
}
.music-single-desc {
padding: 4%;
}
.play-track-name {
column-gap: 2vw;
}
.play-track-name h1 {
font-size: 1.2em;
}
#waveform {
margin-left: -4vw;
margin-right: -4vw;
}
.play-track-name .music-style {
line-height: 1.9;
}
}
/* Input Range */
input[type=range] {
width: 100%;
margin: 7.6px 0;
background-color: transparent;
-webkit-appearance: none;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
background: rgba(153, 153, 255, 0.78);
border: 0;
border-radius: 25px;
width: 100%;
height: 4.8px;
cursor: pointer;
}
input[type=range]::-webkit-slider-thumb {
margin-top: -7.6px;
width: 20px;
height: 20px;
background: var(--accent-color);
border: 0;
border-radius: 11px;
cursor: pointer;
-webkit-appearance: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #9e9eff;
}
input[type=range]::-moz-range-track {
background: rgba(153, 153, 255, 0.78);
border: 0;
border-radius: 25px;
width: 100%;
height: 4.8px;
cursor: pointer;
}
input[type=range]::-moz-range-thumb {
width: 20px;
height: 20px;
background: var(--accent-color);
border: 0;
border-radius: 11px;
cursor: pointer;
}
input[type=range]::-ms-track {
background: transparent;
border-color: transparent;
border-width: 8.5px 0;
color: transparent;
width: 100%;
height: 4.8px;
cursor: pointer;
}
input[type=range]::-ms-fill-lower {
background: #9494ff;
border: 0;
border-radius: 50px;
}
input[type=range]::-ms-fill-upper {
background: rgba(153, 153, 255, 0.78);
border: 0;
border-radius: 50px;
}
input[type=range]::-ms-thumb {
width: 20px;
height: 20px;
background: var(--accent-color);
border: 0;
border-radius: 11px;
cursor: pointer;
margin-top: 0px;
/*Needed to keep the Edge thumb centred*/
}
input[type=range]:focus::-ms-fill-lower {
background: rgba(153, 153, 255, 0.78);
}
input[type=range]:focus::-ms-fill-upper {
background: #9e9eff;
}
/*TODO: Use one of the selectors from https://stackoverflow.com/a/20541859/7077589 and figure out
how to remove the virtical space around the range input in IE*/
@supports (-ms-ime-align:auto) {
/* Pre-Chromium Edge only styles, selector taken from hhttps://stackoverflow.com/a/32202953/7077589 */
input[type=range] {
margin: 0;
/*Edge starts the margin from the thumb, not the track as other browsers do*/
}
}
/* Input Range */
.buy-streaming-wraper {
background: #f5f5f5;
}
.buy-streaming-container {
margin: 0 auto;
padding: 1vw 2vw;
max-width: 1600px;
display: grid;
gap: 0;
grid-template-areas:
"buy streaming-link";
grid-template-rows: repeat(1, auto);
grid-template-columns: repeat(2, 1fr);
column-gap: 20px;
row-gap: 0;
justify-items: stretch;
align-items: start;
justify-content: space-evenly;
align-content: space-evenly;
}
.streaming {
grid-area: streaming-link;
line-height: 0;
align-self : center;
}
.streaming-link {
width: 28px;
display: none;
border: 0;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=60);
-moz-opacity: 0.60;
-khtml-opacity: 0.60;
/* opacity: 0.60; */
}
.streaming-link:after {
content: ''!important;
}
.streaming-link:hover {
border: 0;
}
.streaming-link img {
width: 100%;
height: auto;
aspect-ratio: 1 / 1;
line-height: 0;
}
.buy {
grid-area: buy;
}
.buy svg {
width: 22px;
vertical-align: text-bottom;
}
.buy .button, .buy .wp-block-button__link {
margin: 0;
}
@media only screen and (max-width: 940px) {
.buy-streaming-container {
margin: 0 auto;
padding: 4vw;
display: grid;
gap: 0;
grid-template-areas:
"buy"
"streaming-link";
grid-template-rows: repeat(2, auto);
grid-template-columns: repeat(1, 1fr);
column-gap: 20px;
row-gap: 4vw;
justify-items: stretch;
align-items: start;
justify-content: space-evenly;
align-content: space-evenly;
}
.buy .button, .buy .wp-block-button__link {
width: 100%;
}
.streaming {
justify-self: center;
}
.streaming-link {
width: 28px;
}
}
/* Audio Player */
WordPress × Wavesurfer JS: conclusion
I hope this article will be useful for beginner developers like me.
If you have any questions or suggestions about my implementation, please email me or leave a comment.
Check out more interesting posts on my blog.