Search code examples
javascriptjqueryhtmlcssdraggable

Word-wrap: break-down not working. Text overflow issue in draggable element


Please help to solve this issue. Currently I have a div, that is draggable and the text inside is editable. And here the user can change the text size using input type range.

Is it possible to hide the letters of text-canvas, so that letters coming beyond the border of the image-canvas div and reach the col-sm-8?

Here when the user writes text without space, then that word go beyond the col-sm-8. How to solve this? I use overflow:hidden and word-wrap:breakdown, but it's not working. enter image description here

function submit_button() {
  /* ....Image upload function.. */
}
$(".text-canvas").draggable({
  containment: ".imageupload",
  create: function() {
    $("#text-canvas ").css("width ", 'auto');
  },
  drag: function() {
    $("#text-canvas ").css("width ", 'auto');
  },
  start: function() {
    $("#text-canvas ").css("width ", 'auto');
  },
  stop: function() {
    $("#text-canvas ").css("width ", 'auto');
  }
});

$("#fontsize").on("change", function() {
  var v = $(this).val();
  $('.text-canvas').css('font-size', v + 'px');
});
.text-canvas {
  z-index: 1;
  position: absolute;
}
.imageupload {
  z-index: -1;
}
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

<div class="col-sm-4">
  <div name="anotherdiv">
    <input type="range" min="12" max="54" id="fontsize">
  </div>
</div>
<div class="col-sm-8">
  <div class="parent-canvas">
    <div class="text-canvas" id="text-canvas" contenteditable="true">
      my text
    </div>
    <div class="image-canvas">
      <div class="imageupload" onclick="submit_button()">
        <img src="img.png">
      </div>

    </div>
  </div>
</div>

Then I used .text-canvas{ word-break: break-all; }. Now the text is not going outside of the col-sm-8 but it is still going outside of the image-div.

enter image description here

UPDATE :currently I solved the issue by using padding-right:10%. But I don't think is a good method. Please suggest a correct method.


Solution

  • Solution:

    You need to use the following properties in your .parent-canvas class:

    .parent-canvas {
      display: inline-block; /* Display inline but retain the block-level characteristics */
      overflow: hidden; /* Hide the text if it overflows the container */
      position: relative; /* Text is removed from the normal flow with absolute position, use this to contain it */
    }
    

    After this you have two options, using word-break or max-width in your .text-canvas class:

    .text-canvas {
      word-break: break-all;
    }
    

    Code Snippet:

    function submit_button() {
      /* ....Image upload function.. */
    }
    $(".text-canvas").draggable({
      containment: ".imageupload",
      create: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      drag: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      start: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      stop: function() {
        $("#text-canvas ").css("width ", 'auto');
      }
    });
    
    $("#fontsize").on("change", function() {
      var v = $(this).val();
      $('.text-canvas').css('font-size', v + 'px');
    });
    .text-canvas {
      z-index: 1;
      position: absolute;
    }
    .imageupload {
      z-index: -1;
    }
    .parent-canvas {
      display: inline-block;
      overflow: hidden;
      position: relative;
    }
    .text-canvas {
      word-break: break-all;
    }
    .image-canvas img {
      vertical-align: middle;
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    
    <div class="col-sm-4">
      <div name="anotherdiv">
        <input type="range" min="12" max="54" id="fontsize">
      </div>
    </div>
    <div class="col-sm-8">
      <div class="parent-canvas">
        <div class="text-canvas" id="text-canvas" contenteditable="true">
          my text
        </div>
        <div class="image-canvas">
          <div class="imageupload" onclick="submit_button()">
            <img src="http://placehold.it/100x100">
          </div>
    
        </div>
      </div>
    </div>

    or

    .text-canvas {
      max-width: 100%;
    }
    

    Code Snippet:

    function submit_button() {
      /* ....Image upload function.. */
    }
    $(".text-canvas").draggable({
      containment: ".imageupload",
      create: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      drag: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      start: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      stop: function() {
        $("#text-canvas ").css("width ", 'auto');
      }
    });
    
    $("#fontsize").on("change", function() {
      var v = $(this).val();
      $('.text-canvas').css('font-size', v + 'px');
    });
    .text-canvas {
      z-index: 1;
      position: absolute;
    }
    .imageupload {
      z-index: -1;
    }
    .parent-canvas {
      display: inline-block;
      overflow: hidden;
      position: relative;
    }
    .text-canvas {
      max-width: 100%;
    }
    .image-canvas img {
      vertical-align: middle;
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    
    <div class="col-sm-4">
      <div name="anotherdiv">
        <input type="range" min="12" max="54" id="fontsize">
      </div>
    </div>
    <div class="col-sm-8">
      <div class="parent-canvas">
        <div class="text-canvas" id="text-canvas" contenteditable="true">
          my text
        </div>
        <div class="image-canvas">
          <div class="imageupload" onclick="submit_button()">
            <img src="http://placehold.it/100x100">
          </div>
    
        </div>
      </div>
    </div>


    You can also use both if you like, they do not interfere with one another:

    .text-canvas {
      word-break: break-all;
      max-width: 100%;
    }
    

    Code Snippet:

    function submit_button() {
      /* ....Image upload function.. */
    }
    $(".text-canvas").draggable({
      containment: ".imageupload",
      create: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      drag: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      start: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      stop: function() {
        $("#text-canvas ").css("width ", 'auto');
      }
    });
    
    $("#fontsize").on("change", function() {
      var v = $(this).val();
      $('.text-canvas').css('font-size', v + 'px');
    });
    .text-canvas {
      z-index: 1;
      position: absolute;
    }
    .imageupload {
      z-index: -1;
    }
    .parent-canvas {
      display: inline-block;
      overflow: hidden;
      position: relative;
    }
    .text-canvas {
      word-break: break-all;
      max-width: 100%;
    }
    .image-canvas img {
      vertical-align: middle;
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    
    <div class="col-sm-4">
      <div name="anotherdiv">
        <input type="range" min="12" max="54" id="fontsize">
      </div>
    </div>
    <div class="col-sm-8">
      <div class="parent-canvas">
        <div class="text-canvas" id="text-canvas" contenteditable="true">
          ttttttttttttttttttttttttttttttttttttttt
        </div>
        <div class="image-canvas">
          <div class="imageupload" onclick="submit_button()">
            <img src="http://placehold.it/100x100">
          </div>
    
        </div>
      </div>
    </div>


    jsFiddle


    TESTS:

    Windows 10 (64 bit):

    • Chrome 54.0.2840.71 m
    • FireFox 49.0.2
    • Edge 25.10586.0.0

    IOS 10.1:

    • Iphone 6 Safari Mobile

    Possible UX Improvement:

    In my opinion, a little bit of user experience improvement, at least for Chrome and FF, could be adding the property cursor: grab; and cursor: grabbing; to let the user know it's a draggable element.

    I didn't know it was a draggable item after I posted this answer. I guess I didn't pay real attention to whole question... people tend to interact with things fast.

    You will need to decide if the cursor: text; is better than having the grab and grabbing ones.

    Properties added to jQuery draggable classes:

    .ui-draggable {
      cursor: -webkit-grab;
      cursor: grab;
    }
    .ui-draggable-dragging {
      cursor: -webkit-grabbing;
      cursor: grabbing;
    }
    

    Code Snippet:

    function submit_button() {
      /* ....Image upload function.. */
    }
    $(".text-canvas").draggable({
      containment: ".imageupload",
      create: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      drag: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      start: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      stop: function() {
        $("#text-canvas ").css("width ", 'auto');
      }
    });
    
    $("#fontsize").on("change", function() {
      var v = $(this).val();
      $('.text-canvas').css('font-size', v + 'px');
    });
    .text-canvas {
      z-index: 1;
      position: absolute;
    }
    .imageupload {
      z-index: -1;
    }
    .parent-canvas {
      display: inline-block;
      overflow: hidden;
      position: relative;
    }
    .text-canvas {
      word-break: break-all;
      max-width: 100%;
    }
    .image-canvas img {
      vertical-align: middle;
    }
    .ui-draggable {
      cursor: -webkit-grab;
      cursor: grab;
    }
    .ui-draggable-dragging {
      cursor: -webkit-grabbing;
      cursor: grabbing;
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    
    <div class="col-sm-4">
      <div name="anotherdiv">
        <input type="range" min="12" max="54" id="fontsize">
      </div>
    </div>
    <div class="col-sm-8">
      <div class="parent-canvas">
        <div class="text-canvas" id="text-canvas" contenteditable="true">
          my text
        </div>
        <div class="image-canvas">
          <div class="imageupload" onclick="submit_button()">
            <img src="http://placehold.it/100x100">
          </div>
    
        </div>
      </div>
    </div>


    Notes:

    • To remove the unwanted space under the img element, use the property vertical-align: middle;.

    EDIT:

    To prevent the text from overflowing vertically when font-size is increased, you need to set height: auto; to the .text-canvas class.

    You can do this in different ways, one could be doing this:

    $("#fontsize").on("change", function() {
      var v = $(this).val();
      $('.text-canvas').css({
        'font-size': v + 'px',
        'height': 'auto'
      });
    });
    

    This will set the auto value overriding the one set by jQuery UI.

    In the demo, the image is quite small and the font-size can get too big, making its container dimensions exceed its parent's, make sure to control that in production.

    Code Snippet:

    function submit_button() {
      /* ....Image upload function.. */
    }
    $(".text-canvas").draggable({
      containment: ".imageupload",
      create: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      drag: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      start: function() {
        $("#text-canvas ").css("width ", 'auto');
      },
      stop: function() {
        $("#text-canvas ").css("width ", 'auto');
      }
    });
    
    $("#fontsize").on("change", function() {
      var v = $(this).val();
      $('.text-canvas').css({
        'font-size': v + 'px',
        'height': 'auto'
      });
    });
    .text-canvas {
      z-index: 1;
      position: absolute;
    }
    .imageupload {
      z-index: -1;
    }
    .parent-canvas {
      display: inline-block;
      overflow: hidden;
      position: relative;
    }
    .text-canvas {
      word-break: break-all;
      max-width: 100%;
    }
    .image-canvas img {
      vertical-align: middle;
    }
    .ui-draggable {
      cursor: -webkit-grab;
      cursor: grab;
    }
    .ui-draggable-dragging {
      cursor: -webkit-grabbing;
      cursor: grabbing;
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
    
    <div class="col-sm-4">
      <div name="anotherdiv">
        <input type="range" min="12" max="54" id="fontsize">
      </div>
    </div>
    <div class="col-sm-8">
      <div class="parent-canvas">
        <div class="text-canvas" id="text-canvas" contenteditable="true">
          my text
        </div>
        <div class="image-canvas">
          <div class="imageupload" onclick="submit_button()">
            <img src="http://placehold.it/100x100">
          </div>
    
        </div>
      </div>
    </div>