cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

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

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

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

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

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.

            
              <svg>

<div id="header">
  <hr data-line="The Hitchhiker's Guide to the Galaxy">
</div>

<div id="display">
  <img>
  <p>Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun.</p>
  <p>Orbiting this at a distance of roughly ninety-two million miles is an utterly insignificant little blue green planet whose ape descended life forms are so amazingly primitive that they still think digital watches are a pretty neat idea.</p>
  <p>This planet has - or rather had - a problem, which was this: most of the people on it were unhappy for pretty much of the time. Many solutions were suggested for this problem, but most of these were largely concerned with the movements of small green pieces of paper, which is odd because on the whole it wasn't the small green pieces of paper that were unhappy.</p>
  <p>And so the problem remained; lots of the people were mean, and most of them were miserable, even the ones with digital watches.</p>
  <p>Many were increasingly of the opinion that they'd all made a big mistake in coming down from the trees in the first place. And some said that even the trees had been a bad move, and that no one should ever have left the oceans.</p>
  <p>And then, one Thursday, nearly two thousand years after one man had been nailed to a tree for saying how great it would be to be nice to people for a change, one girl sitting on her own in a small cafe in Rickmansworth suddenly realized what it was that had been going wrong all this time, and she finally knew how the world could be made a good and happy place. This time it was right, it would work, and no one would have to get nailed to anything.</p>
  <p>Sadly, however, before she could get to a phone to tell anyone about it, a terribly stupid catastrophe occurred, and the idea was lost forever.</p>
  <p>This is not her story.</p>
</div>

<div id="footer">
  <hr data-line="Douglas Adams">
</div>
  
<div id="config">
  <div>
    <form name="configForm">
      <h2>Configuration:</h2>
      <div id="controls">
        <label for="letterNum">A-Z</label>
        <input id="letterNum" name="letterNum" type="range" min="1" max="26"> 
        <label for="letterSize">Size</label>
        <input id="letterSize" name="letterSize" type="range" min="100" max="500"> 
        <label for="xPos">X Offet</label>
        <input id="xPos" name="xPos" type="range" min="0" max="180"> 
        <label for="yPos">Y Offset</label>
        <input id="yPos" name="yPos" type="range" min="0" max="350"> 
        <label for="fonts">Font</label>
        <select onchange="chooseFont()" id="fonts" name="fonts">
            <option value="Aclonica">Aclonica</option>
            <option value="AguafinaScript">Aguafina Script</option>
            <option value="Anton">Anton</option>
            <option value="Arbutus">Arbutus</option>
            <option value="arimaMadurai">Arima Madurai</option>
            <option value="averiaSerifLibre">Averia Serif Libre</option>
            <option value="baloo">Baloo</option>
            <option value="bangers">Bangers</option>
            <option value="bevan">Bevan</option>
            <option value="blackOpsOne">Black Ops One</option>
            <option value="bowlbyOneSC">Bowlby One SC</option>
            <option value="bubblegumSans">Bubblegum Sans</option>
            <option value="bungee">Bungee</option>
            <option value="bungeeinline">Bungee Inline</option>
            <option value="carterOne">Carter One</option>
            <option value="cevicheOne">Ceviche One</option>
            <option value="changaOne">Changa One</option>
            <option value="chelseaMarket">Chelsea Market</option>
            <option value="chewy">Chewy</option>
            <option value="cinzelDecorative">Cinzel Decorative</option>
            <option value="contrailOne">Contrail One</option>
            <option value="Corben">Corben</option>
            <option value="EmblemaOne">Emblema One</option>
            <option value="fontdinerSwanky">Fontdiner Swanky</option>
            <option value="freckleFace">Freckle Face</option>
            <option value="frederika">Fredericka the Great</option>
            <option value="fugazOne">Fugaz One</option>
            <option value="graduate">Graduate</option>
            <option value="kellySlab">Kelly Slab</option>
            <option value="knewave">Knewave</option>
            <option value="lilitaOne">Lilita One</option>
            <option value="limelight">Limelight</option>
            <option value="lobster">Lobster</option>
            <option value="londrinaSolid">Londrina Solid</option>
            <option value="loveYaLikeASister">Love Ya Like A Sister</option>
            <option value="Merriweather">Merriweather</option>
            <option value="MrDafoe">Mr Dafoe</option>
            <option value="OleoScriptSwashCaps" selected>Oleo Script Swash Caps</option>
            <option value="OpenSans">Open Sans</option>
            <option value="overlock">Overlock</option>
            <option value="playball">Playball</option>
            <option value="pollerOne">Poller One</option>
            <option value="pressStart2P">Press Start 2P</option>
            <option value="racingSansOne">Racing Sans One</option>
            <option value="rammettoOne">Rammetto One</option>
            <option value="Roboto">Roboto</option>
            <option value="Sancreek">Sancreek</option>
            <option value="shrikhand">Shrikhand</option>
            <option value="sigmarOne">Sigmar One</option>
            <option value="SpicyRice">Spicy Rice</option>
            <option value="SonsieOne">Sonsie One</option>
            <option value="TitanOne">Titan One</option>
            <option value="Vollkorn">Vollkorn</option>
        </select>
        <span>Styles</span>
        <span>
          <input type="radio" id="style0" name="styles" value="style0" onclick="chooseStyle(this);"
       checked />
          <label for="style0">Plain</label>
        </span>
        <span>
          <input type="radio" id="style7" name="styles" value="style7" onclick="chooseStyle(this);"
       />
          <label for="style7">Sandwich</label>
        </span>
        <span>&nbsp;</span>
        <span>
          <input type="radio" id="style6" name="styles" value="style6" onclick="chooseStyle(this);"
       />
          <label for="style6">Eighties</label>
        </span>
        <span>
          <input type="radio" id="style2" name="styles" value="style2" onclick="chooseStyle(this);"
       />
          <label for="style2">Drop shadow</label>
        </span>
      </div>
    </div>
    <div>
      <h2>Credits/Resources:</h2>
      <div id="credits">
        <ul>
          <li><a href="https://twitter.com/rosieebob" target="_blank">@rosieebob</a> - <a href="https://codepen.io/KristopherVanSant/" target="_blank">shape-outside inspiration</a></li>
          <li><a href="https://codepen.io/enxaneta/" target="_blank">@enxaneta</a> - <a href="https://codepen.io/enxaneta/pen/LbdjZR" target="_blank">shape-outside: url + SVG</a></li>
          <li><a href="https://twitter.com/nikoskip" target="_blank">@nikoskip</a> - <a href="https://nikoskip.me/gfonts.php" target="_blank">Download Google Fonts SVG files</a></li>
        <li><a href="https://twitter.com/davidwalshblog" target="_blank">David Walsh</a> - <a href="https://davidwalsh.name/css-content-attr" target="_blank">CSS content and attr</a></li>
          <li><a href="https://twitter.com/dirkweber" target="_blank">Dirk Weber</a> - <a href="https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/" target="_blank">Why the SVG Filter is Awesome</a></li>
          <li><a href="https://twitter.com/SaraSoueidan" target="_blank">Sara Soueidan</a> - <a href="https://www.sarasoueidan.com/blog/svg-filters/" target="_blank">SVG Filters: The Crash Course</a></li>

        </ul>
      </div>
    </div>
   </form
</div>

            
          
!
            
              body{
  font-family: 'Lato', sans-serif;
  color: #2E282A;
  display: grid;
  grid-template-columns: 1fr 300px;
  grid-auto-rows: 70px minmax(calc(100vh - 140px),auto) 70px;
}

#header, #footer{
  grid-column: 1;
  padding: 25px 80px 0 80px;
}

hr {
    overflow: visible; /* For IE */
    padding: 0;
    border: none;
    border-top: medium double #333;
    color: #333;
    text-align: center;
}

hr:after {
    content: "";
    display: inline-block;
    position: relative;
    top: -0.7em;
    font-size: 1.2em;
    padding: 0 0.25em;
    background: white;
}

#header > hr:after {
  content: attr(data-line);
}
#footer > hr:after {
  content: attr(data-line);
}
#display{
  grid-column: 1;
  position: relative;
  margin: 0px;
}
svg{
  visibility: hidden;
  position: absolute;
  height: 100px;
}
img{
  shape-margin: 15px;
  float: left;
  filter: url(#filter);
  -webkit-filter: url(#filter);
}

p {
  margin-bottom: 10px;
  margin-left: 80px;
  margin-right: 80px;
}

p:first-of-type {
  margin-top: 150px;
}

p:first-of-type::first-letter {
  font-size: 0;    
}


#config {
  grid-row: 1;
  grid-column: 2;
  grid-row-end: span 3;
  background: #495C70;
  color: #E1DEE3;
  padding: 20px;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 300px 1fr;
}
h2 {
  font-size: 1.1em;
  margin: 10px 0;
}
#config li {
  margin-bottom: 10px;
}
#config a {
  font-size: 0.8em;
  line-height: 1.3em;
  color: #E1DEE3;
}
#controls{
  display: grid;
  grid-template-columns: auto 1fr 1fr;
  grid-gap: 10px;
  font-size: 0.7em;
  margin-bottom: 30px;
}
#controls > label{
  margin-top: 3px;
}
#controls > input{
  width:100%;
  grid-column-end: span 2;
}
#controls > select{
  grid-column-end: span 2;
}

@media only screen and (max-width: 800px) {
  body {
    grid-template-columns: 1fr;
    grid-auto-rows: auto;
  }
  #config {
    grid-row: 1;
    grid-column: 1;
    grid-template-columns: 1fr 280px;
    grid-template-rows: auto;
    grid-column-gap: 40px;
  }
}

@media only screen and (max-width: 600px) {
  #config {
    grid-row: 1;
    grid-column: 1;
    grid-template-columns: 1fr;
    grid-column-gap: 40px;
  }
  #config div:nth-of-type(2){
    display: none;
  }
}
            
          
!
            
              // get the first letter of the text 
var unicodeVal = document.getElementById('display').getElementsByTagName('p')[0].innerText.substring(0,1);
var fontFile = "";
var currentStyle = "style0"
var allGlyphs;
var svgdisplay = document.querySelector("svg");
var svgimg = document.querySelector("img");
var svgimgHeight = 300;
var xOffset = 0;
var yOffset = 150;
var dValue = "";
var alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];

// loads SVG font file for selected font
function chooseFont() {
  // font file is selected in drop-down menu
  fontFile = document.getElementById("fonts").value;
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      // get all Glyph elements from XML
      var xmlDoc = this.responseXML;
      allGlyphs = xmlDoc.getElementsByTagName("glyph");
      showLetter();
    }
  };
  xhttp.open("GET", "https://s3-us-west-2.amazonaws.com/s.cdpn.io/881020/"+fontFile+".svg", true);
  xhttp.send();
}

function showLetter(){
  for(var i=0;i<allGlyphs.length;i++){
    if(allGlyphs[i].getAttribute("unicode")==unicodeVal){
      // get "d" value for currently selected letter 
      dValue = allGlyphs[i].getAttribute("d")
    }
  }
  svgdisplay.innerHTML = eval(currentStyle).filter + '<path id="letterPath" unicode="'+ unicodeVal +'" d="'+ dValue +'" />';
  var displayPath = document.getElementById("letterPath");
  var displayBox = displayPath.getBBox();
  var scaleFactor = 1000/displayBox.height;
  svgdisplay.setAttribute("viewBox", "0 0 "+((scaleFactor*displayBox.width)+200)+" "+1200);
  displayPath.setAttribute("transform","scale("+scaleFactor+", "+(0-scaleFactor)+") translate("+ (100-scaleFactor*displayBox.x) +", "+ (0-(scaleFactor*displayBox.y+displayBox.height+100)) +")");

  svgStr = '<svg width="'+ ((scaleFactor*displayBox.width) + 200) +'px" height="'+ 1200 +'px" version="1.1" xmlns="http://www.w3.org/2000/svg"><path transform="scale('+scaleFactor+', '+(0-scaleFactor)+') translate('+ (100-scaleFactor*displayBox.x) +', '+ (0-(scaleFactor*displayBox.y+displayBox.height+100)) +')" unicode="'+ unicodeVal +'" d="'+ dValue +'" /></svg>';

  var svgStrEncode = encodeURI(svgStr);
  var srcStr = 'data:image/svg+xml,'+svgStrEncode;
  console.log(decodeURI(srcStr)); 
  svgimg.src = srcStr;
  svgimg.style.webkitShapeOutside = 'url("'+srcStr+'")';
  svgimg.style.shapeOutside = 'url("'+srcStr+'")';
  sizeLetter();
}

function sizeLetter(){
  svgimg.style.height = svgimgHeight+"px";
}

function chooseStyle(newStyleBtn) {
  currentStyle = newStyleBtn.value;
  showLetter();
}

var inputLetter = document.getElementById("letterNum");
inputLetter.addEventListener("input", onInputLetterFunc, false);
inputLetter.value = 6;

function onInputLetterFunc(){
  unicodeVal = alphabet[inputLetter.value-1];
  showLetter();
}

var inputSize = document.getElementById("letterSize");
inputSize.addEventListener("input", onInputSizeFunc, false);
inputSize.value = svgimgHeight;

function onInputSizeFunc(){
  svgimgHeight = inputSize.value;
  sizeLetter();
}

var inputX = document.getElementById("xPos");
inputX.addEventListener("input", onInputXFunc, false);
inputX.value = xOffset;

function onInputXFunc(){
  svgimg.style.marginLeft = inputX.value+"px";
}

var inputY = document.getElementById("yPos");
inputY.addEventListener("input", onInputYFunc, false);
inputY.value = yOffset;

function onInputYFunc(){
  document.getElementsByTagName('P')[0].style.marginTop = inputY.value+"px";
}

var style0 = { filter:`
    <defs>     
      <filter id="filter">
          <feFlood flood-color="#2E282A" result="COLOR-default"></feFlood>
          <feComposite in="COLOR-default" in2="SourceGraphic" operator="in" result="extrusion0"</feComposite>
      </filter>
    </defs>
`};



var style2 = { filter:`<defs>
  <filter id="filter" x="-20%" y="-20%" width="140%" height="140%">
    <feFlood flood-color="#F77F00" result="COLOR-orange"></feFlood>
    <feComposite in="COLOR-orange" in2="SourceGraphic" operator="in" result="ColouredOriginal"></feComposite>
    <feOffset in="SourceAlpha" dx="10" dy="10"></feOffset>
    <feGaussianBlur stdDeviation="10" result="DROP"></feGaussianBlur>
    <feFlood flood-color="#bbb" result="COLOR"></feFlood>
    <feComposite
      in="COLOR" in2="DROP"
      operator="in" result="SHADOW">
    </feComposite>
    <feMerge>
      <feMergeNode in="SHADOW" />
      <feMergeNode in="ColouredOriginal" />
    </feMerge>
  </filter>
</defs>
`};

var style6 = { filter:`
    <defs>     
      <filter id="filter">
          <feFlood flood-color="#E40066" result="COLOR-pink"></feFlood>
          <feFlood flood-color="#03CEA4" result="COLOR-shadow"></feFlood>
          <feFlood flood-color="#345995" result="COLOR-dark"></feFlood>
          <feImage xlink:href="data:image/svg+xml;charset=utf-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%221000px%22%20height%3D%221000px%22%20%20%3E%0A%09%3Cdefs%3E%0A%09%09%3Cpattern%20id%3D%22pattern%22%20patternUnits%3D%22userSpaceOnUse%22%20width%3D%225px%22%20height%3D%225px%22%20viewBox%3D%220%200%205%205%22%20%3E%0A%09%09%09%3Cpolygon%20points%3D%225%2C0%204.012%2C0%205%2C0.989%20%09%22%2F%3E%0A%09%09%09%3Cpolygon%20points%3D%225%2C5%200%2C0%200%2C0.989%204.01%2C5%20%09%22%2F%3E%0A%09%09%3C%2Fpattern%3E%0A%09%3C%2Fdefs%3E%0A%09%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%23pattern)%22%20%2F%3E%0A%3C%2Fsvg%3E" x="0" y="0" width="1000" height="1000" result="IMAGE-stripes"></feImage>
          <feMorphology operator="dilate" radius="4" in="SourceAlpha" result="dilatedLetter"></feMorphology>
         <feConvolveMatrix order="8,8" divisor="1" kernelMatrix="1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1" in="dilatedLetter" result="extrudedLetter"></feConvolveMatrix>

          <feOffset dx="4" dy="4" in="extrudedLetter" result="offetExtrusion1"></feOffset>
          <feOffset dx="8" dy="8" in="extrudedLetter" result="offetExtrusion2"></feOffset>
          <feOffset dx="10" dy="10" in="extrudedLetter" result="offetExtrusion3"></feOffset>
          <feOffset dx="14" dy="14" in="extrudedLetter" result="offetExtrusion4"></feOffset>

          <feMerge result="superExtrusion">
            <feMergeNode in="offetExtrusion1"></feMergeNode>
            <feMergeNode in="offetExtrusion2"></feMergeNode>
            <feMergeNode in="offetExtrusion3"></feMergeNode>
            <feMergeNode in="offetExtrusion4"></feMergeNode>
          </feMerge>
          <feComposite in="COLOR-pink" in2="SourceGraphic" operator="in" result="ColouredOriginal"></feComposite>
          <feComposite in="COLOR-shadow" in2="superExtrusion" operator="in" result="superExtrusion"></feComposite>
          <feComposite in="COLOR-dark" in2="dilatedLetter" operator="in" result="dilatedLetter"></feComposite>
          <feComposite in="COLOR-dark" in2="IMAGE-stripes" operator="in" result="IMAGE-stripes"></feComposite>
          <feComposite operator="in" in="IMAGE-stripes" in2="superExtrusion" result="topStripes"></feComposite>

          <feMerge result="fullMerge">
            <feMergeNode in="superExtrusion"></feMergeNode>
            <feMergeNode in="topStripes"></feMergeNode>
            <feMergeNode in="dilatedLetter"></feMergeNode>
            <feMergeNode in="ColouredOriginal"></feMergeNode>
          </feMerge>
          <feOffset dx="-14" dy="-14" in="fullMerge" result="fullMerge"></feOffset>


      </filter>
    </defs>
`};
var style7 = { filter:`
    <defs>     
      <filter id="filter">
          <feFlood flood-color="#FA735A" result="COLOR-salmon"></feFlood>
          <feFlood flood-color="#B1B1B2" result="COLOR-grey"></feFlood>
          <feFlood flood-color="#BFD1DD" result="COLOR-blue"></feFlood>
         <feConvolveMatrix order="8,8" divisor="1" kernelMatrix="1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1" in="SourceAlpha" result="extrudedLetter"></feConvolveMatrix>

          <feOffset dx="4" dy="4" in="extrudedLetter" result="offetExtrusion1"></feOffset>
          <feOffset dx="8" dy="8" in="extrudedLetter" result="offetExtrusion2"></feOffset>
          <feOffset dx="10" dy="10" in="extrudedLetter" result="offetExtrusion3"></feOffset>
          <feOffset dx="14" dy="14" in="extrudedLetter" result="offetExtrusion4"></feOffset>

          <feMerge result="extrusion1">
            <feMergeNode in="offetExtrusion1"></feMergeNode>
          </feMerge>
          <feMerge result="extrusion2">
            <feMergeNode in="offetExtrusion2"></feMergeNode>
            <feMergeNode in="offetExtrusion3"></feMergeNode>
            <feMergeNode in="offetExtrusion4"></feMergeNode>
          </feMerge>
          <feComposite in="COLOR-salmon" in2="SourceGraphic" operator="in" result="extrusion0"></feComposite>
          <feComposite in="COLOR-blue" in2="extrusion1" operator="in" result="extrusion1"></feComposite>
          <feComposite in="COLOR-grey" in2="extrusion2" operator="in" result="extrusion2"></feComposite>
          <feMerge result="fullMerge">
            <feMergeNode in="extrusion2"></feMergeNode>
            <feMergeNode in="extrusion1"></feMergeNode>
            <feMergeNode in="extrusion0"></feMergeNode>
          </feMerge>
          <feOffset dx="-14" dy="-14" in="fullMerge" result="fullMerge"></feOffset>
      </filter>
    </defs>
`};

// display the chosen font, which includes displaying the drop cap first letter
chooseFont();


            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console