Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

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

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

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.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

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

Visit your global Editor Settings.

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='100', step='any', value='50')
          button(data-preset='height:50') 1:2
          button(data-preset='height:100') 1:1
          button(data-preset='height:86.6', onclick='iso.click()') √3:2 (equilateral)
      li
        label
          span angle
          input(name='angle', type='range', min='-100', max='100', 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 0.3s
  border-color hsl(160, 0%, 20%) hsl(150, 0%, 10%) !important
  filter none
  &:hover
    padding 10px
    background hsl(160, 0%, 40%)
    

.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-grid
    
    input
      width: 1.5em;
      display: block;
      height: 1.5em;
      appearance: block;
      position absolute
      appearance: inherit;
    
      &: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 .1em .2em !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 1em
    line-height 1
    vertical-align middle
    color #fff
    display inline-block
    margin-right 5px
    // padding-right 5px
    // border-right 1px solid #999
  
  &: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/100 + 1) / 2) + 'px'
  css['border-' + bdr[3] + '-width'] = Math.round(val.size * (val.angle/100 + 1) / 2) + 'px'
  css['border-' + bdr[2]] = Math.round(val.size * val.height/100) + '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