Negera CSS-variabel

:root {
  --margin: 20px;
}

/* Set margin-left of the container to -20px */
.container {
  margin-left: calc(var(--margin) * -1);
}

Lägg till klass och attribut på heading för att t.ex. göra en horisontell linje efter en rubrik

I JS nedan skapar vi en checkruta på headingblocken som i sin tur lägger på en klass på elementet om ibockad. Längst ner hittar vi ipmAddExtraProps där vi lägger till den inmatade texten som data-attribut på elementet. På så vis kan vi använda samma text i en ::before-deklaration. Väldigt omständigt men det är ett sätt att göra det på om man inte kan injecta <span> och grejer runt texten.

import assign from 'lodash.assign';
import { appendClassNames } from './helpers/appendClassNames';

const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, SelectControl, CheckboxControl } = wp.components;
const { addFilter } = wp.hooks;
const { __, _x } = wp.i18n;


/**
 * Add spacing control attribute to block.
 *
 * @param {object} settings Current block settings.
 * @param {string} name Name of block.
 *
 * @returns {object} Modified block settings.
 */
const addControlAttributes = (settings, name) => {

	// Do nothing if it's another block than our defined ones.
	if (name !== 'core/heading') {
		return settings;
	}

	// Use Lodash's assign to gracefully handle if attributes are undefined
	settings.attributes = assign(settings.attributes, {
		headingline: {
			type: 'boolean',
			default: false
		}
	});

	return settings;
};



/**
 * Create HOC to add spacing control to inspector controls of block.
 */
const additionalSettings = createHigherOrderComponent((BlockEdit) => {
	return (props) => {

		// Do nothing if it's another block than our defined ones.
		if (props.name !== 'core/heading') {
			return (
				<BlockEdit {...props} />
			);
		}

		const { headingline } = props.attributes;

		return (
			<Fragment>
				<BlockEdit {...props} />
				<InspectorControls>
					<PanelBody
						title={_x('Heading settings','heading line label', 'ipm-gef')}
						initialOpen={false}
					>
						<CheckboxControl
							label={_x('Line', 'heading line label', 'ipm-gef')}
							checked={ headingline }
							onChange={(selectedLineOption) => {
								props.attributes.className = appendClassNames(props.attributes.className, 'has-heading-line', headingline, selectedLineOption)
								props.setAttributes({
									headingline: selectedLineOption,
								});
							}}
						/>

					</PanelBody>
				</InspectorControls>
			</Fragment>
		);
	};
}, 'additionalSettings');

addFilter('blocks.registerBlockType', 'ipm/settings/heading-attributes', addControlAttributes);
addFilter('editor.BlockEdit', 'ipm/settings/heading-controls', additionalSettings);



function ipmAddExtraProps(extraProps, blockType, attributes) {
	if (blockType.name === 'core/heading' && attributes.headingline === true) {

		return {
			...extraProps,
			'data-heading-content': attributes.content,
		};
	}

	return extraProps;
}
addFilter('blocks.getSaveContent.extraProps', 'ipm/add-extra-props', ipmAddExtraProps);
&.has-heading-line {
		background-color: var(--color-white);
		padding-right: 1rem;
		position: relative;
		display: flex;

		&::before {
			background: var(--color-gray--darkest);
			content: "";
			display: inline-block;
			width: calc(100%);
			height: 1px;
			position: absolute;
			right: 0;
			top: 50%;
			transform: translateY(-50%);
		}

		&::after {
			content: attr(data-heading-content);
			position: absolute;
			background: #fff;
			display: block;
			padding-right: 1rem;
		}
	}

Men, det finns en stor nackdel med detta och det är att text i pseudoelement inte är markerbar.

CSS Grid to the rescue:

&.has-heading-line {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		align-items: center;
		grid-gap: 1rem;

		&::after {
			content: '';
			border-top: 1px solid var(--color-gray--darkest);
		}
}

Automatisk kalkylering av bredd på flexade kolumner baserat på antal och gap

.wrapper {
    --gap: 1rem;
    --columns: 1;
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap);

    @media (min-width: 64em) {
        --gap: 2rem;
        --columns: 2;
    }
    @media (min-width: 100em) {
        --gap: 3rem;
        --columns: 3;
    }
    @media (min-width: 100em) {
        --gap: 3rem;
        --columns: 4;
    }

    .item {
        width: 100%;

        @media (min-width: 48em) {
            width: calc((100% / var(--columns)) - var(--gap) + (var(--gap) / var(--columns)));
        }
    }
}

Toggla show/hide med CSS

Flex

.wrapper {
  display: flex;
}

.inner {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.5s ease-out;
}

.wrapper.is-open .inner {
  max-height: 100%;
}

Just be sure there’s an extra div between the wrapper and the inner element:

<div class="wrapper">
  <div>
    <div class="inner">Expandable content</div>
  </div>
</div>

Grid

This one is a bit simpler, and probably a little more understandable. Make a CSS grid with a single grid item. All you have to do is transition grid-template-rows from 0fr to 1fr, so the grid item transitions to its auto height:

.wrapper {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.5s ease-out;
}

.wrapper.is-open {
  grid-template-rows: 1fr;
}

.inner {
  overflow: hidden;
}
<div class="wrapper">
  <div class="inner">Expandable content</div>
</div>

The one caveat to both of these is you can’t add any padding to the inner element. If you need padding, you have to add one more extra element inside the collapsed element and put the padding on that.

Max-height

.section {
  overflow:hidden;
  transition:max-height 0.3s ease-out; // note that we're transitioning max-height, not height!
  height:auto;
  max-height:600px; // still have to hard-code a value!
}
.section.collapsed {
  max-height:0;
}

There are two crucial downsides to this

One is obvious, and one is subtle. The obvious disadvantage is that we still have to hard-code a maximum height for the element, even if we don’t have to hard-code the height itself. Depending on your situation, maybe you can guarantee that you won’t need more height than that. But if not, it’s a pretty big compromise. The second, less obvious downside, is that the transition length will not actually be what you specify unless the content height works out to be exactly the same as max-height. For example, say your content is 600px tall, and your max-height is transitioning from 0px to 1000px with a duration of 1 second. How long will it take the element to get to 600px? 0.6 seconds! The max-height will continue transitioning, but the real height will stop changing once it reaches the end of its content. This will be even more pronounced if your transition is using a nonlinear timing function. If the transition is fast at the beginning and slow at the end, your section will expand quickly and collapse slowly. Not ideal. Still, transitions are relatively subjective, so in cases where this technique is otherwise appropriate, it could be an acceptable tradeoff.

Technique 2: transform: scaleY()

It’s important to note a couple of things about the nature of these transformations:

  1. They operate on the element’s visual representation as if it were simply an image, rather than a DOM element. This means, for example, that an element scaled up too far will look pixellated, since its DOM was originally rendered onto fewer pixels than it now spans.
  2. They do not trigger reflows. Again, the transform doesn’t know or care about the element’s DOM structure, only about the “picture” the browser drew of it. This is both the reason this technique works and its biggest downside.
.section {
  overflow:hidden;
  transition:transform 0.3s ease-out; // note that we're transitioning transform, not height!
  height:auto;
  transform:scaleY(1); // implicit, but good to specify explicitly
  transform-origin:top; // keep the top of the element in the same place. this is optional.
}
.section.collapsed {
  transform:scaleY(0); // *squish*
}

Ta bort inline style på Active Campaign embeds

/* Remove inline <style></style> added by Active Campaign embeds */
(function($) {

	$.fn.removeACStyle = function() {

		let acForm = $('._form');

		if (acForm.length == 0)
			return;

		acForm.siblings('style').remove();
		acForm.parent().siblings('style').remove();
	}

	$(function() {
		$('body').removeACStyle();
	});

})(jQuery);

Gråskaleeffekt på bilder

img {
filter: url("data:image/svg+xml;utf8,#grayscale"); /* Firefox 10+, Firefox on Android */
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
filter: grayscale(100%);
filter: gray; /* IE 6-9 */
}
img:hover {
-webkit-filter: none;
-moz-filter: none;
-ms-filter: none;
filter: none;
}

Cross-browser-kompatibel ner till IE6.

Fixa så höjden stämmer på ett < svg >-objekt (cross-browser)

IE11 är en av flera browsers som inte fixar att kirra höjd på ett svg-objekt ordentligt. Följande metod kan funka som ett fulhack för att få det att fungera. Se till att ha med viewBox i din svg.

  • Räkna ratio på viewboxen (höjd/bredd) – exempelvis blir ett värde på 0,1234 = 12,34%
  • Omslut med en div (ex. class=”svg-wrapper”)

I CSSen sätter du:

.svg-wrapper {
   padding-bottom: [din ratio]% //(se procentvärdet ovan)
   position: relative;
}

.svg-wrapper svg {
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: auto; //(alltså 100%)
}

 

Vertical align anything

.element {
  position: relative;
  top: 50%;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
}

Notering: Opera har aldrig kört prefix på transforms och Firefox stödjer oprefixat sen v.16 (alltså behövs inget -moz- egentligen). Från IE9 och uppåt. Läs mer på ZeroSixThree.