Slider with JavaScript
* {
    margin: 0;
    padding: 0;
    border: 0;
    list-style-type: none;
    transition: all .5s;
}


First, I wouldn't do this. This resets styles on all elements, including other elements on the page. One rule I follow in CSS is not to unnecessarily override styles, especially the defaults. Unless you have a good reason to do so or you have custom base style for everything (like bootstrap).

.gallery{...}
.gallery .button{...}
.gallery .items{...}

//or

.gallery{...}
.gallery-button{...}
.gallery-items{...}


Another good practice in CSS is to namespace your styles. Selectors after another selector only take effect to descendants of the former selector. This makes it possible to limit the coverage of the style down to a certain element's descendants. Another way to do it is to use a naming scheme that's similar to namespacing. This makes your styles mean something, appear like it has heirarchy, and does not accidentally override other elements' styles.

&lt;div class="gallery"
  &lt;ul&gt;
    &lt;li&gt;&lt;img src="" /&gt;&lt;/li&gt;
    &lt;li&gt;&lt;img src="" /&gt;&lt;/li&gt;
    &lt;li&gt;&lt;img src="" /&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;


The markup can also be simplified. A slider is simply a list of things. The markup should be built in a way that it does resemble a list semantically. Then you improve using JS from there. You can add the buttons dynamically in JS, as they mean nothing in the markup.

;(function(){

 // Your code here

}());


One thing I find annoying in JS is that everything you write is exposed to the global namespace by default. Your code will be prone to conflicting names, or mutating values. One thing you can do to prevent being a victim, or being the cause of conflicts is to enclose your code inside a closure. This prevents your code from being overwritten. To prevent your code overwriting stuff, you must declare stuff in this scope (use var).

var imageWidth = 300;

function generateXTranslate(index, width){
  return 'translateX(-' + (index * width) + 'px)';
}

nextBtn.addEventListener('click', function () {
  if (index === numOfImgs - 1) return;
  sliderWrapper.style.transform = generateXTranslate(++index, imageWidth);
});

prevBtn.addEventListener('click', function () {
  if (!index) return;
  sliderWrapper.style.transform = generateXTranslate(--index, imageWidth);
});


A lot of the code is redundant. You can simplify by taking out common code and moving them out to their function. In here, you can move out the setting of the transform into a function. Also, you can simply track down the current image as an index instead of the pixels, since the translated pixels is just a function of the index times the width of the images.