diff --git a/README.md b/README.md index 179b3be..c88b4e1 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,117 @@ BASIC USAGE ### Creating CSS +You can create CSS from scratch like this: + +```php +use Pop\Css\Css; +use Pop\Css\Selector; + +$css = new Css(); + +$html = new Selector('html'); +$html->setProperties([ + 'margin' => 0, + 'padding' => 0, + 'background-color' => '#fff', + 'font-family' => 'Arial, sans-serif' +]); + +$login = new Selector('#login'); +$login->setProperty('margin', 0); +$login->setProperty('padding', 0); + +echo $css; +``` + +The above code will produce: + +```css +html { + margin: 0; + padding: 0; + background-color: #fff; + font-family: Arial, sans-serif; +} + +#login { + margin: 0; + padding: 0; +} +``` + +### Using Media Queries + +You can also add media queries to your CSS as well: + +```php +use Pop\Css\Css; +use Pop\Css\Media; +use Pop\Css\Selector; + +$css = new Css(); + +$html = new Selector('html'); +$html->setProperties([ + 'margin' => 0, + 'padding' => 0, + 'background-color' => '#fff', + 'font-family' => 'Arial, sans-serif' +]); + +$login = new Selector('#login'); +$login->setProperty('margin', 0); +$login->setProperty('padding', 0); +$login->setProperty('width', '50%'); + +$css->addSelectors([$html, $login]); + +$media = new Media('screen'); +$media->setFeature('max-width', '480px'); +$media['#login'] = new Selector(); +$media['#login']->setProperty('width', '75%'); + +$css->addMedia($media); + +echo $css; +``` + +The above code will produce: + +```css +html { + margin: 0; + padding: 0; + background-color: #fff; + font-family: Arial, sans-serif; +} + +#login { + margin: 0; + padding: 0; + width: 50%; +} + +@media screen and (max-width: 480px) { + #login { + width: 75%; + } + +} +``` + +### Adding Comments + +You can add comments to the css as well: + ```php use Pop\Css\Css; +use Pop\Css\Media; use Pop\Css\Selector; +use Pop\Css\Comment; $css = new Css(); +$css->addComment(new Comment('This is a top level comment')); $html = new Selector('html'); $html->setProperties([ @@ -40,6 +146,18 @@ $html->setProperties([ $login = new Selector('#login'); $login->setProperty('margin', 0); $login->setProperty('padding', 0); +$login->setProperty('width', '50%'); +$login->addComment(new Comment('This is a comment for the #login selector')); + +$css->addSelectors([$html, $login]); + +$media = new Media('screen'); +$media->setFeature('max-width', '480px'); +$media['#login'] = new Selector(); +$media['#login']->setProperty('width', '75%'); +$media['#login']->addComment(new Comment('And this is a comment for the #login selector within the media query.')); + +$css->addMedia($media); echo $css; ``` @@ -47,6 +165,10 @@ echo $css; The above code will produce: ```css +/** + * This is a top level comment + */ + html { margin: 0; padding: 0; @@ -54,10 +176,60 @@ html { font-family: Arial, sans-serif; } +/** + * This is a comment for the #login selector + */ + #login { margin: 0; padding: 0; + width: 50%; } + +@media screen and (max-width: 480px) { + /** + * And this is a comment for the #login selector within the media query. + */ + + #login { + width: 75%; + } + +} +``` + +### Minifying the CSS + +Minify the CSS like this: + +```php +use Pop\Css\Css; +use Pop\Css\Selector; + +$css = new Css(); + +$html = new Selector('html'); +$html->setProperties([ + 'margin' => 0, + 'padding' => 0, + 'background-color' => '#fff', + 'font-family' => 'Arial, sans-serif' +]); + +$login = new Selector('#login'); +$login->setProperty('margin', 0); +$login->setProperty('padding', 0); +$login->setProperty('width', '50%'); + +$css->addSelectors([$html, $login]); +$css->minify(); +echo $css; +``` + +Which produces: + +```css +html{margin:0;padding:0;background-color:#fff;font-family:Arial, sans-serif;}#login{margin:0;padding:0;width:50%;} ``` ### Parsing a CSS file diff --git a/src/AbstractCss.php b/src/AbstractCss.php index aae8d2f..c818bdb 100644 --- a/src/AbstractCss.php +++ b/src/AbstractCss.php @@ -23,7 +23,7 @@ * @license http://www.popphp.org/license New BSD License * @version 3.0.0 */ -abstract class AbstractCss +abstract class AbstractCss implements \ArrayAccess { /** @@ -184,4 +184,54 @@ public function isMinified() return $this->minify; } + /** + * ArrayAccess offsetExists + * + * @param mixed $offset + * @return boolean + */ + public function offsetExists($offset) + { + return $this->hasSelector($offset); + } + + /** + * ArrayAccess offsetGet + * + * @param mixed $offset + * @return mixed + */ + public function offsetGet($offset) + { + return $this->getSelector($offset); + } + + /** + * ArrayAccess offsetSet + * + * @param mixed $offset + * @param mixed $value + * @throws Exception + * @return void + */ + public function offsetSet($offset, $value) + { + if (!($value instanceof Selector)) { + throw new Exception('Error: The value passed must be an instance of Pop\Css\Selector'); + } + $value->setName($offset); + $this->addSelector($value); + } + + /** + * ArrayAccess offsetUnset + * + * @param mixed $offset + * @return void + */ + public function offsetUnset($offset) + { + $this->removeSelector($offset); + } + } \ No newline at end of file diff --git a/src/Media.php b/src/Media.php index b98f8b6..651b90a 100644 --- a/src/Media.php +++ b/src/Media.php @@ -222,10 +222,17 @@ public function render() if (null !== $this->type) { $css .= ' ' . $this->type; } + + if (!empty($this->condition) || !empty($this->type)) { + $css .= ' and'; + } + if (count($this->features) > 0) { + $features = []; foreach ($this->features as $feature => $value) { - $css .= ' and (' . $feature . ': ' . $value .')'; + $features[] = '(' . $feature . ': ' . $value .')'; } + $css .= ' ' . implode(' and ', $features); } $css .= ' {'; diff --git a/src/Selector.php b/src/Selector.php index 02d061c..626d3e6 100644 --- a/src/Selector.php +++ b/src/Selector.php @@ -76,9 +76,11 @@ class Selector implements \ArrayAccess, \Countable, \IteratorAggregate * @param string $name * @param int $tabSize */ - public function __construct($name, $tabSize = 4) + public function __construct($name = null, $tabSize = 4) { - $this->setName($name); + if (null !== $name) { + $this->setName($name); + } $this->setTabSize($tabSize); } diff --git a/tests/CssTest.php b/tests/CssTest.php index 6d8e892..d50284e 100644 --- a/tests/CssTest.php +++ b/tests/CssTest.php @@ -125,4 +125,27 @@ public function testRender() $this->assertContains('html {', $cssString); } + public function testOffsetMethods() + { + $css = new Css\Css(); + $css->addSelectors([ + new Css\Selector('html'), + new Css\Selector('#login') + ]); + + $css['.login-div'] = new Css\Selector(); + $this->assertTrue(isset($css['#login'])); + $this->assertTrue(isset($css['.login-div'])); + $this->assertInstanceOf('Pop\Css\Selector', $css['#login']); + unset($css['#login']); + $this->assertFalse(isset($css['#login'])); + } + + public function testOffsetSetException() + { + $this->expectException('Pop\Css\Exception'); + $css = new Css\Css(); + $css['.login-div'] = [123]; + } + } \ No newline at end of file