Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

HTML

            
              h1 CSS triangle generator
.main
  .ctrl
    ul#values
      li
        label
          span size
          input(name='size', type='range', min='0', max='400', step='any', value='200')
      li
        label
          span height
          input(name='height', type='range', min='0', max='2', step='any', value='0.5')
          button(data-preset='height:0.5') 1:2
          button(data-preset='height:1') 1:1
          button(data-preset='height:0.866', onclick='iso.click()') √3:2 (equilateral)
      li
        label
          span angle
          input(name='angle', type='range', min='-1', max='1', step='any', value='0')
          button#iso(data-preset='angle:0') isosceles
    ul#direction
      li
        label
          input(type='radio', name='dir', value='top', checked='')
          span ↑
      li
        label
          input(type='radio', name='dir', value='right')
          span →
      li
        label
          input(type='radio', name='dir', value='bottom')
          span ↓
      li
        label
          input(type='radio', name='dir', value='left')
          span ←
  .out
    pre.
    div.tri
      input#show(type='checkbox', name='')
      label(for='show')  show all borders
      #triangle

            
          
!

CSS

            
              *
*:before
*:after
  box-sizing border-box
html
  font-size 16px

h1
  text-align center
  font-weight normal
  font-size 1.5em
  margin 0.5em


ul,li
  display block
  list-style none
  padding 0
  margin 0


#show:checked~#triangle
  transition border 0.3s
  border-color hsl(160, 0%, 20%) hsl(150, 0%, 10%) !important
  filter none

.tri
  margin 20px

#triangle
  //transition border .3s
  width 0
  margin-top 20px
  filter drop-shadow(0 0 5px rgba(#f,.5))


#values
  padding 0
  display block
  list-style none
  
  >li
    background rgba(#000, 0.1)
    padding 1px
    margin 10px 0
  
  label
    margin 10px 0
    display block
  
  span
    display inline-block
    width 50px
    text-align right
    vertical-align middle
  
  input
    vertical-align middle
    width 300px
  


#direction
  background rgba(#000, .1)
  padding 10px
  font-size 1.5em
  
  >li
    text-align center
    display inline-block
    
    input
      display none
      
      &:checked+span
        background #363
        color white
        text-shadow 0 0 5px white
        box-shadow 0px 0px 0px 1px rgba(#fff, 0.5)
    
    span
      display block
      background #444
      vertical-align middle
      line-height 1.3
      padding 0px 0px
      width 1.5em
      height 1.5em
      transition .3s background-color
      box-shadow 0px 0px 0px 1px rgba(#fff, 0.3)
      
      &:hover
        background-color #336

html
  background #258
  color #ace
  min-height 100%
  margin 10px

pre
  background-color rgba(0, 0, 0, 0.5)
  margin 20px -10px
  color #fff
  padding 10px
  
  .prop
    color #ff3
  
  .value
    color #5ff
  
  .size
    color #f55

button
  background #444
  border none
  color #ddd
  margin-left 10px
  //border-radius 0.2em
  vertical-align middle
  padding 0 5px !important
  box-shadow 0px 0px 0px 1px rgba(#fff, 0.3)
  transition .3s background-color
  
  &:hover
    background #336
    box-shadow 0px 0px 0px 1px rgba(#fff, 0.5)
  
  &:before
    // content '◎ '
    content '◇ '
    font-size 1.4em
    line-height 1
    vertical-align middle
    color #fff
    display inline-block
    border-right 1px solid #999
    margin-right 5px
    padding-right 5px
  
  &:disabled
    //box-shadow none
    background-color #363
    pointer-events none
    
    &:before
      // content '◉ '
      content '◈ '

.main
  border-top 1px solid transparent
  
@media (min-width 1111px)
  pre
    margin 10px 0
  .main
    display flex
  .ctrl
    flex-grow 1
  .out
    margin-left 10px
    width 600px
    
.main
  border-top 1px solid transparent
@media (max-width 1110px) and (max-height 600px)
  .out
    display flex
    flex-wrap wrap
    align-items flex-start
    >*
      flex 1 1 0
            
          
!

JS

            
              const rng = document.queryAll('#values input[type=range]')
const pst = document.queryAll('[data-preset]')
const tri = document.query('#triangle')
const pre = document.query('pre')
const val = {}
const bdr = ['top', 'right', 'bottom', 'left']
let dir  = document.queryAll('#direction input')

rng.forEach((elm) => {
  val[elm.name] = +elm.value
})

draw()

pst.forEach((btn) => {
  const data = btn.dataset.preset.split(':')
  const input = rng.find((a) => a.name === data[0])
  const val = data[1]
  
  const event = document.createEvent('Event');
  event.initEvent('input', true, false);
  
  function checkButton(){
    btn.disabled = (input.value === val)
  }
  input.addEventListener('input', checkButton)
  btn.addEventListener('click', () => {
    input.value = val
    input.dispatchEvent(event);
    checkButton()
  })
  checkButton()
})

rng.forEach((elm) => {
  elm.addEventListener('input', () => {
    val[elm.name] = +elm.value
    draw()
  })
})

dir.forEach((elm) => {
  elm.addEventListener('change', () => {
    dir = elm.value
    while (bdr[0] !== dir)
      bdr.push(bdr.shift())
    draw()
  })
})

dir = dir.find((elm) => elm.checked).value

draw()

function draw() {
  let style = ''
  const css = {
    width: '0',
    height: '0',
    border: '0 solid transparent'
  }
  css['border-' + bdr[1] + '-width'] = Math.round(val.size * (-val.angle + 1) / 2) + 'px'
  css['border-' + bdr[3] + '-width'] = Math.round(val.size * (val.angle + 1) / 2) + 'px'
  css['border-' + bdr[2]] = Math.round(val.size * val.height) + 'px solid black'

  Object.assign(tri.style, css)

  Object.entries(css).forEach(([k, v]) => {
    v = v.replace(/(\d+(px)?)/g, '<span class="size">$1</span>')
    style += '<span class="prop">' + k + '</span>: <span class="value">' + v + '</span>;\n'
  })

  pre.innerHTML = style

}
            
          
!
999px

Console