Brightside – TYPO3 web design & development agency

Open knowledge

Image width by using percentages

Setting image width and height in pixels doesn't really make much sense, especially in nowadays responsive websites. It's a hit and miss concept from the very beginning. Only designers aim what would a 700 x 400 px image look like in an actual content. But wait what happens on the screen that's not even 700 px wide?

% is easy to understand

Everybody has a rough idea how wide would be 30% image or image set in content and that over 100% will probably go out of the box.

What will it be:

  1. using css_styled_content as custom content layouts should be possible without coding another extension
  2. set image width using the % of the outer container
  3. fully automatic image scaling
  4. easy to manipulate image content through templates as no hardcoded image px in database
  5. default with for in text pictures if not manually set
  6. default 100% width for pictures above or below the text if not manually set

Real life example is here...

TypoScript

This is one way to do it and can be improved a lot but as a concept it works pretty well.



###
# Page TsConfig to manipulate backend fields
###
TCEFORM.tt_content {
  imagewidth.label = Width in % (percentage of the outer container)
  imageheight.disabled = 1
}

###
# TypoScript Constants to clean up few things, will be using CSS
###
styles.content.imgtext {
  maxW = 1300
  maxWInText = 1300
  colSpace = 0
  textMargin = 0
  rowSpace = 0
}
# with in percentage for the default image in text and image in text no wrap
defaultImgInTextWidth = 50

###
# TypoScript Setup to manipulate default css_styled_content images
###
tt_content.image.20 {
  1 {
    file.width.stdWrap.stdWrap.orderedStdWrap {
      10.wrap = |
      20.wrap = |+{$defaultImgInTextWidth}
      20.wrap.if.value = 15
      20.wrap.if.isGreaterThan.field = imageorient
      20.wrap.if.isFalse.field = imagewidth
      25.wrap = |+100
      25.wrap.if.value = 16
      25.wrap.if.isLessThan.field = imageorient
      25.wrap.if.isFalse.field = imagewidth
      30.wrap = |*{$styles.content.imgtext.maxW}/100
      40.wrap = |/{register:imageCount}
      40.wrap.if {
        value.data = register:imageCount
        isLessThan.field = imagecols
        negate = 1
      }
      50.wrap = |/{field:imagecols}
      50.wrap.if {
        value.data = register:imageCount
        isGreaterThan.field = imagecols
        negate = 1
      }
      60.wrap = |*{register:imageCount}
      60.wrap.if {
         value.data = register:imageCount
         equals.field = imagecols
      }
    }
    file.width.stdWrap.prioriCalc = 1
    file.width.stdWrap.stdWrap.insertData = 1
  }
  layout {
# intext-right-nowrap change the text and image order
    25.value = <div class="csc-textpic csc-textpic-intext-right-nowrap###CLASSES###">###TEXT######IMAGES###</div>
    25.override = <div class="csc-textpic csc-textpic-responsive csc-textpic-intext-right-nowrap###CLASSES###">###TEXT######IMAGES###</div>
  }
# works with HTML5 page type only
  rendering {
    singleNoCaption {
      allStdWrap.dataWrap.override = |
      allStdWrap.dataWrap.override.stdWrap.orderedStdWrap {
        10.wrap = <div class="csc-textpic-imagewrap" style="width: {field:imagewidth}%" data-csc-images="{register:imageCount}" data-csc-cols="{field:imagecols}"> | </div>
        10.wrap.if.isTrue.field = imagewidth
        20.wrap = <div class="csc-textpic-imagewrap" style="{$defaultImgInTextWidth}%" data-csc-images="{register:imageCount}" data-csc-cols="{field:imagecols}"> | </div>
        20.wrap.if.isFalse.field = imagewidth
      }
      columnStdWrap.wrap = <div class="csc-textpic-imagecolumn###CLASSES###"> | </div><div class="csc-textpic-space ###CLASSES###"></div>
    }
    noCaption {
      allStdWrap.dataWrap.override = |
      allStdWrap.dataWrap.override.stdWrap.orderedStdWrap {
        10.wrap = <div class="csc-textpic-imagewrap" style="width: {field:imagewidth}%" data-csc-images="{register:imageCount}" data-csc-cols="{field:imagecols}"> | </div>
        10.wrap.if.isTrue.field = imagewidth
        20.wrap = <div class="csc-textpic-imagewrap" style="width: {$defaultImgInTextWidth}%" data-csc-images="{register:imageCount}" data-csc-cols="{field:imagecols}"> | </div>
        20.wrap.if.value = 15
        20.wrap.if.isGreaterThan.field = imageorient
        20.wrap.if.isFalse.field = imagewidth
        30.wrap = <div class="csc-textpic-imagewrap" style="width: 100%" data-csc-images="{register:imageCount}" data-csc-cols="{field:imagecols}"> | </div>
        30.wrap.if.value = 16
        30.wrap.if.isLessThan.field = imageorient
        30.wrap.if.isFalse.field = imagewidth
      }
      columnStdWrap.wrap = <div class="csc-textpic-imagecolumn###CLASSES###"> | </div><div class="csc-textpic-space ###CLASSES###"></div>
    }
    splitCaption < .noCaption
    splitCaption {
      singleStdWrap.wrap.override = <figure class="csc-textpic-image">|###CAPTION###</figure>
      caption.required = 1
      caption.wrap.override = <figcaption class="csc-textpic-caption###CLASSES###"> | </figcaption>
    }
    singleCaption < .splitCaption
  }
}

CSS


/* general layout settings */

	.csc-textpic-imagewrap {margin-top: 0.3em;}

	.csc-textpic-imagewrap, .csc-textpic-center-inner {display: table; table-layout:fixed; border-collapse: collapse; width: 100%}
	.csc-textpic-intext-left-nowrap, .csc-textpic-intext-right-nowrap {display: table}

	.csc-textpic-imagerow {display: table-row}
	.csc-textpic-intext-left-nowrap .csc-textpic-imagewrap, .csc-textpic-intext-left-nowrap .csc-textpic-text,
	.csc-textpic-intext-right-nowrap .csc-textpic-imagewrap, .csc-textpic-intext-right-nowrap .csc-textpic-text,
	.csc-textpic-imagecolumn, .csc-textpic-space {display: table-cell; vertical-align: top; padding-bottom: 0.5em;}

	.csc-textpic-space {width: 0.5em}
	.csc-textpic-space.csc-textpic-lastcol {display: none}

	.csc-textpic-image a {display: block;  line-height: 0; font-size: 0}
	.csc-textpic-image img {width: 100%; height: auto; padding: 0; margin: 0}

	.csc-textpic-caption {display: inline-block; line-height: 1.4em; font-size: 0.875em; color: #666}


/* image placements */
	.csc-textpic-center .csc-textpic-imagewrap {margin: auto}
	.csc-textpic-right .csc-textpic-imagewrap {margin-left: auto}

	.csc-textpic-intext-left .csc-textpic-imagewrap {float: left; margin-right: 1.6em}
	.csc-textpic-intext-right .csc-textpic-imagewrap {float: right; margin-left: 1.6em}

	.csc-textpic-intext-left-nowrap .csc-textpic-imagewrap, .csc-textpic-intext-right-nowrap .csc-textpic-text {padding-right: 0.8em}
	.csc-textpic-intext-left-nowrap .csc-textpic-text, .csc-textpic-intext-right-nowrap .csc-textpic-imagewrap  {padding-left: 0.8em}

Comments