<div class="container">
  <div class="tooltips">
    <div class="arrow">
      <div class="arrow-inner"></div>
    </div>
    <div class="tooltips-content">我是一个提示框</div>
  </div>
</div>
<div class="container">
  <section>
    <h2>Tooltips 主体</h2>
    <div class="forms">
      <div class="control">
        <label for="padding">padding:</label>
        <input type="range" step="1" min="0" max="40" value="5" id="padding" />
        <span>px</span>
      </div>
      
      <div class="control">
        <label for="borderRadius">border-radius:</label>
        <input type="range" step="1" min="0" max="20" value="5" id="borderRadius" />
        <span>px</span>
      </div>
      
      <div class="control">
        <label for="borderWidth">border-width:</label>
        <input type="range" step="1" min="0" max="6" value="0" id="borderWidth" />
        <span>px</span>
      </div>
      
      <div class="control">
        <label for="color">color:</label>
        <input type="color" id="color" value="#333333" />
      </div>
      
      <div class="control">
        <label for="backgroundColor">background-color:</label>
        <input type="color" id="backgroundColor" value="#fffff" />
      </div>
      
      <div class="control">
        <label for="borderColor">border-color:</label>
        <input type="color" id="borderColor" value="#ffffff" />
      </div>
    </div>
  </section>
  <section>
    <h2>Tooltips 三角形</h2>
    <div class="forms">
      <div class="control" id="radios">
        <label><input type="radio" name="direction" value="top" class="radios" id="top">向上</label>
        <label><input type="radio" name="direction" value="right" class="radios" id="right">向右</label>
        <label><input type="radio" name="direction" value="bottom" checked class="radios" id="bottom">向下</label>
        <label><input type="radio" name="direction" value="left" class="radios" id="left">向左</label>
      </div>
      <div class="control">
        <label for="position">三角形位置:</label>
        <input type="range" step=".5" min="0" max="200" value="5" id="position" />
        <span>px</span>
      </div>
      <div class="control">
        <label for="triangleHeight">三角形高度:</label>
        <input type="range" step=".5" min="0" max="30" value="20" id="triangleHeight" />
        <span>px</span>
      </div>
    </div>
  </section>
</div>
@import url('https://fonts.googleapis.com/css?family=Fjalla+One');

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: #25333A;
  display: flex;
  min-height: 100vh;
  justify-content: space-around;
  color: #ffffff;
  font-family: 'Fjalla One', sans-serif;
  padding: 2vh;
  font-size: 14px;
}

.container {
  min-width: 30vw;
  border: 1px dashed #fff;
  padding: 2vw;
  margin: 1vw;
  border-radius: 10px;
  display: flex;
  
  
  &:nth-child(1) {
    justify-content: center;
    align-items: center;
  }
  
  &:nth-child(2) {
    flex: 1;
  }
}
.control {
  display: grid;
  gap: 10px;
  grid-template-columns: 2fr 4fr 1fr;
  place-align: center;
  align-items: center;
  
  label {
    text-align: right;
    white-space: nowrap;
  }
}
#radios {
  grid-template-columns: repeat(4, 1fr);
  
  input {
    margin-right: 4px;
  }
}
.control:not(:last-child){
  margin-bottom: 1em;
}

h2 {
  margin-bottom: 1.5em;
  text-align: center;
}

section {
  margin: 10px;
  min-width: calc((100% - 10px) / 2);
    
  &:not(:last-child) {
      border-right: 3px double #fff;
  }
}

input[type="color"] {
    display: block;
    width: 6vh;
    height: 6vh;
    padding: 2px;
    border: 1px solid #ced4da;
    border-radius: .25rem;
}

// Tooltips Style
.tooltips {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  
  
  // CSS Custom Property for Tooltips
  --padding: 10px;
  --borderRadius: 5px;
  --borderWidth: 0px;
  --color: #333;
  --backgroundColor: #fff;
  --borderColor: #fff;
  --triangleHeight: 10px;
  --triangleColor: var(--backgroundColor);
  --triangleBorderColor: var(--borderColor);
  --triangleBorderWidth: var(--borderWidth);
  --position: 10px;
  
  background-color: var(--backgroundColor);
  color: var(--color);
  padding: var(--padding);
  border-radius: var(--borderRadius);
  border: var(--borderWidth) solid var(--borderColor);
  
  .arrow {
    position: absolute;
    top: 100%;
    overflow: hidden;
    
    width: calc(var(--triangleHeight) * 1.41);
    height: var(--triangleHeight);
    left: var(--position); 
  }
  
  .arrow-inner {
      content: '';
      display: block;
      width: 100%;
      height: 100%;
      transform: rotate(315deg);
      transform-origin: left top;
      
      background-color: var(--triangleColor);
      border: var(--triangleBorderWidth) solid var(--triangleBorderColor);
    }
}

@media (max-width: 445px) {
  body {
    flex-direction: column;
  }
  
  .container {
    min-width: 80vw;
    margin: 2vw 0;
    
    &:nth-child(1) {
      min-height: 30vmin;
    }
    
    &:nth-child(2) {
      flex-direction: column;
      flex: auto;
      
      section:nth-child(1) {
        border: none;
      }
    }
  }
}
View Compiled
const tooltipsEle = document.querySelector('.tooltips');
const arrowWrapperEle = document.querySelector('.arrow'); 
const arrowBoxEle = document.querySelector('.arrow-inner'); 

const tooltipsPadding = document.querySelector('#padding');
const tooltipsBorderRadius = document.querySelector('#borderRadius');
const tooltipsBorderWidth = document.querySelector('#borderWidth');
const tooltipsBorderColor = document.querySelector('#borderColor');
const tooltipsBackgrouondColor = document.querySelector('#backgroundColor');
const tooltipsColor = document.querySelector('#color');

const tooltipsTriangleHeight = document.querySelector('#triangleHeight');
const tooltipsTrianglePosition = document.querySelector('#position');

const tooltipsTriangleDectionRadios = document.querySelectorAll('.radios');
console.log(tooltipsTriangleDectionRadios)

tooltipsPadding.addEventListener('change', function(e){
  tooltipsEle.style.setProperty('--padding', `${e.target.value}px`);
})

tooltipsBorderRadius.addEventListener('change', function(e){
  tooltipsEle.style.setProperty('--borderRadius', `${e.target.value}px`);
})

tooltipsBorderWidth.addEventListener('change', function(e){
  tooltipsEle.style.setProperty('--borderWidth', `${e.target.value}px`);
})

tooltipsBorderColor.addEventListener('change', function(e){
  tooltipsEle.style.setProperty('--borderColor', e.target.value);
})

tooltipsBackgrouondColor.addEventListener('change', function(e){
  tooltipsEle.style.setProperty('--backgroundColor', e.target.value);
})

tooltipsColor.addEventListener('change', function(e){
  tooltipsEle.style.setProperty('--color', e.target.value);
})

tooltipsTriangleHeight.addEventListener('change', function(e){
  tooltipsEle.style.setProperty('--triangleHeight', `${e.target.value}px`);
})

tooltipsTrianglePosition.addEventListener('change', function(e){
  tooltipsEle.style.setProperty('--position', `${e.target.value}px`);
})

tooltipsTriangleDectionRadios.forEach (input => {
  input.addEventListener('change', function(e){
    if(this.id === 'top') {
      arrowWrapperEle.style.cssText = `
        top: auto;
        bottom: 100%;
      `
      arrowBoxEle.style.cssText = `
        transform-origin: left bottom;
        transform: rotate(45deg);
      `
    } else if(this.id === 'right'){
      console.log(e.target.value, arrowWrapperEle)
      arrowWrapperEle.style.cssText = `
        top: var(--position);
        left: 100%;
        width: var(--triangleHeight);
        height: calc(var(--triangleHeight) * 1.41);
      `
      arrowBoxEle.style.cssText = `
        transform-origin: left top;
        transform: rotate(45deg);
      `
    } else if(this.id === 'bottom') {
      arrowWrapperEle.style.cssText = '';
      arrowBoxEle.style.cssText = ''
    } else if(this.id === 'left') {
      arrowWrapperEle.style.cssText = `
        top: var(--position);
        right: 100%;
        left: auto;
        width: var(--triangleHeight);
        height: calc(var(--triangleHeight) * 1.41);
      `
      arrowBoxEle.style.cssText = `
        transform-origin: right top;
        transform: rotate(-45deg);
      `
    }
  });
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.